我试图编写 bash 脚本,该脚本将在某些 fs 事件上运行命令。到目前为止,我已经成功构建了 fswatch 并对其进行了配置,但我无法让 bash 将字符串拆分为数组,然后切换我正在监视的所有不同事件的大小写(如果存在)。
我总是会得到某种形式的not a valid identifier
,我甚至不知道那是什么意思。
#!/usr/bin/bash
IFS=" "
fswatch -0 -xnr --event 2 --event 4 --event 8 --event 16 --event 128 --event 256 ./ \
| xargs -0 -n 1 -I {path} sh -c "echo {path}; read -a arr {path};"
sh: line 0: read: `/run/media/twiggeh/Storage/projects/Clone/client/src/script.sh': not a valid identifier
答案1
该not a valid identifier
消息告诉您不能使用文件路径作为变量名(您的代码将语句扩展read
为类似的内容read -a arr /path/to/my/directory
。您正在调用sh
,它不一定是诸如bash
甚至可以理解的shell -a arr
(dash
例如,会报告dash: 1: read: Illegal option -a
)。bash
如果需要,请指定bash
。
但是,我认为最好将代码彻底改过来(就像这样)。以下bash
代码将处理不仅包含空格而且还包含其他奇怪字符(换行符等)的文件名:
while IFS= read -d '' -r line
do
# Split at the last space
file="${line% *}" event="${line##* }"
# Event and file are now separated
printf "event=%s, file=%s.\n" "$event" "$file"
# Put your case statements here
# case "$event" ... esac
done < <(fswatch -0 -xnr --event 2 --event 4 --event 8 --event 16 --event 128 --event 256 ./)
重定向 fromfswatch...
允许主 while 循环保留在父 shell 的上下文中,这样在case
...esac
部分设置的任何变量都可以被脚本的其余部分访问。使用更明显的fswatch ... | while ... do ... done
构造会将while
循环放入子 shell 中,从而阻止它可能设置的任何变量在脚本的其余部分可用。