Bash for循环与空格

时间:2015-09-25 14:07:49

标签: bash shell for-loop

我想做这样的事情:

COMMANDS='"ls /" "df ~" "du -hs ~/Devel/"'
for i in $COMMANDS; do
    echo $i
done

结果如下:

ls /
df ~
du -hs ~/Devel/

但是我找不到合适的空格语法。

2 个答案:

答案 0 :(得分:9)

COMMANDS=("ls /" "df ~" "du -hs ~/Devel/")
for i in "${COMMANDS[@]}"; do 
  echo "$i"
done

这使用数组来存储命令。此功能也可在kshzsh中使用,但不能在sh中使用。

数组的行为类似于"$@"参数数组。在for上应用"${ARRAY_NAME[@]}"循环(引号很重要)将连续为您提供每个项目。如果您省略引号,则默认情况下它们会被一起刷新,并在您IFS环境变量('\t''\n'' '中的分隔符上进行拆分)。

答案 1 :(得分:5)

我建议你不要那样做。首先,它比简单的写作更长,更复杂

ls /
df ~
du -hs ~/Devel/

其次,扁平字符串无法存储嵌套的,以空格分隔的字符串。没有办法(是的,我忽略eval)来区分分隔命令和命令空间的空格。您可以将数组用于简单命令,但不能嵌套数组,因此只要其中一个命令的参数包含空格,就会回到原始问题。

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!