【问题标题】:Bash for loop with spaces带有空格的 Bash for 循环
【发布时间】: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/

但我找不到正确的空格语法。

【问题讨论】:

    标签: bash shell for-loop


    【解决方案1】:
    COMMANDS=("ls /" "df ~" "du -hs ~/Devel/")
    for i in "${COMMANDS[@]}"; do 
      echo "$i"
    done
    

    这使用一个数组来存储命令。此功能在ksh、zsh 中也可用,但在sh 中不可用。

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

    【讨论】:

    • 这是对所问具体问题的正确答案,但正如 chepner 指出的那样,这是走错路的正确步骤。
    • @GordonDavisson 有些人考虑他们是否可以,而另一些人则考虑他们是否应该。我倾向于第一种。 :D
    • 但不适用于 sh :'(
    • @kokbira A sh 解决方案:用不在命令中的字符分隔命令,然后在该字符上拆分,例如,COMMANDS='ls / df ~ du -hs ~/Devel/' ( IFS=' '; for c in $COMMANDS; do echo "$c"; done ) (使用制表符作为分隔符)。
    • @PSkocik,更新,我可以在我的 bash 脚本中使用数组,所以我爱上了它
    【解决方案2】:

    我建议你根本不要这样做。首先,它比简单的写要长得多,也更复杂

    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!

    【讨论】:

    • 我知道您的答案更正确,但我标记了另一个答案,因为它在大多数情况下更简单且足够。不过谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-10-23
    • 2014-12-09
    • 2015-10-01
    • 2014-01-20
    • 2020-04-19
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多