Bash for循环与空格

dar*_*aud 7 bash shell for-loop

我想做这样的事情:

COMMANDS='"ls /" "df ~" "du -hs ~/Devel/"'
for i in $COMMANDS; do
    echo $i
done
Run Code Online (Sandbox Code Playgroud)

结果如下:

ls /
df ~
du -hs ~/Devel/
Run Code Online (Sandbox Code Playgroud)

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

PSk*_*cik 10

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

这使用数组来存储命令.此功能也可用ksh,zsh但不是在sh.

数组的行为类似于"$@"参数数组.应用for循环"${ARRAY_NAME[@]}"(引号很重要)将连续为您提供每个项目.如果省略了引号,一切都会smushed在一起,分割存在于您的分隔IFS的环境变量('\t','\n'并且' '默认情况下).


che*_*ner 5

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

ls /
df ~
du -hs ~/Devel/
Run Code Online (Sandbox Code Playgroud)

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

commands=("ls /" "df ~" "du -hs ~/Devel")  # OK, but...
commands=("ls \"foo bar\"" "echo 'hello world'")  # No.
Run Code Online (Sandbox Code Playgroud)

如果希望脚本能够运行用户指定的任意命令,请将其源文件改为已知目录(即实现插件系统).

command_dir=~/myscript_plugins
for f in "$command_dir"; do
    source "$f"
done
Run Code Online (Sandbox Code Playgroud)

其中$command_dir包含您要运行的每个命令的一个文件.

或者,定义一系列函数,并将它们的名称存储在一个字符串中(函数名称不能包含空格,因此不需要数组):

lister () { ls /; }
dfer () { df ~; }
duer () { du -hs ~/Devel; }

commands="lister dfer duer"
for command in $commands; do 
    $command
done
Run Code Online (Sandbox Code Playgroud)

要么

commands=(lister dfer duer)
for command in "${commands[@]}"; do
    $command
done
Run Code Online (Sandbox Code Playgroud)

进一步阅读:我试图将命令放在变量中,但复杂的情况总是失败!