【发布时间】:2015-12-23 09:32:35
【问题描述】:
我想做这样的事情:
COMMANDS='"ls /" "df ~" "du -hs ~/Devel/"'
for i in $COMMANDS; do
echo $i
done
结果会在哪里:
ls /
df ~
du -hs ~/Devel/
但我找不到正确的空格语法。
【问题讨论】:
我想做这样的事情:
COMMANDS='"ls /" "df ~" "du -hs ~/Devel/"'
for i in $COMMANDS; do
echo $i
done
结果会在哪里:
ls /
df ~
du -hs ~/Devel/
但我找不到正确的空格语法。
【问题讨论】:
COMMANDS=("ls /" "df ~" "du -hs ~/Devel/")
for i in "${COMMANDS[@]}"; do
echo "$i"
done
这使用一个数组来存储命令。此功能在ksh、zsh 中也可用,但在sh 中不可用。
数组的行为类似于 "$@" 参数数组。在"${ARRAY_NAME[@]}" 上应用for 循环(引号很重要)将为您连续提供每个项目。如果您省略引号,它们将全部混合在一起,并在 IFS 环境变量(默认为 '\t'、'\n' 和 ' ')中存在的分隔符上拆分。
【讨论】:
COMMANDS='ls / df ~ du -hs ~/Devel/' ( IFS=' '; for c in $COMMANDS; do echo "$c"; done ) (使用制表符作为分隔符)。
我建议你根本不要这样做。首先,它比简单的写要长得多,也更复杂
ls /
df ~
du -hs ~/Devel/
第二,扁平字符串不能存储嵌套的、以空格分隔的字符串。没有办法(是的,我忽略了eval)来区分分隔命令的空格和分隔命令中的参数的空格。您可以为 simple 命令使用数组,但不能嵌套数组,因此一旦您的某个命令的参数包含空格,您就会回到原来的问题。
commands=("ls /" "df ~" "du -hs ~/Devel") # OK, but...
commands=("ls \"foo bar\"" "echo 'hello world'") # No.
如果您希望您的脚本能够运行用户指定的任意命令,请改为使用已知目录中的源文件(即实现插件系统)。
command_dir=~/myscript_plugins
for f in "$command_dir"; do
source "$f"
done
其中$command_dir 为您要运行的每个命令包含一个文件。
或者,定义一系列函数,并将它们的名称存储在一个字符串中(函数名称不能包含空格,因此不需要数组):
lister () { ls /; }
dfer () { df ~; }
duer () { du -hs ~/Devel; }
commands="lister dfer duer"
for command in $commands; do
$command
done
或
commands=(lister dfer duer)
for command in "${commands[@]}"; do
$command
done
延伸阅读:I'm trying to put a command in a variable, but the complex cases always fail!
【讨论】: