How can I expand a Bash array as arguments to `fswatch`?

64 Views Asked by At

Here are the details of my setup. I have the following files:

config.json

{
    "paths": ["/Users/First Folder", "/Users/Second Folder"]
}

test.sh

#!/bin/zsh
monitored_paths=$(jq -r '.paths[]' config.json)
fswatch --verbose "${monitored_paths[@]}"

The paths key in the JSON array needs to be processed by jq and then expanded as arguments. However, when executing test.sh, I encounter this output:

Output:

start_monitor: Adding path: /Users/First Folder
/Users/Second Folder

My expectation is to have:

start_monitor: Adding path: /Users/First Folder
start_monitor: Adding path: /Users/Second Folder

In summary, I aim to monitor two files, but it seems only one file is being monitored. How can I resolve this issue?

EDIT:

Used exact output by request in the comments.

2

There are 2 best solutions below

16
markp-fuso On BEST ANSWER

NOTE: Following answers were based on the bash tag that was originally attributed to the question; the tag has since been changed to zsh; I don't use zsh but from comments by OP:

  • the while/read loop works in zsh
  • the mapfile does not work in zsh

As mentioned in comments the current monitored_paths assignment populates the variable with a single (2-line) string:

$ typeset -p monitored_paths
declare -a monitored_paths=([0]=$'/Users/First Folder\n/Users/Second Folder')

Notice the embedded linefeed (\n) between the 2 paths.

This entire 2-line construct is fed to fswatch as a single path.

A couple options for populating monitored_paths as an array:

while/read loop:

monitored_paths=()

while read -r path
do
    monitored_paths+=("$path")
done < <(jq -r '.paths[]' config.json)

mapfile:

mapfile -t monitored_paths < <(jq -r '.paths[]' config.json)

Both of these create/populate the array:

$ typeset -p monitored_paths
declare -a monitored_paths=([0]="/Users/First Folder" [1]="/Users/Second Folder")

From here OP's current code should function as expected:

fswatch --verbose "${monitored_paths[@]}"
7
yvs2014 On

in shell syntax from shebang of your example

#!/bin/zsh
typeset -a monitored_paths
jq -r '.paths[]' config.json | while read -r p; do monitored_paths+="$p"; done
fswatch --verbose $monitored_paths