【问题标题】:How to properly nest Bash backticks如何正确嵌套 Bash 反引号
【发布时间】:2011-02-09 01:32:49
【问题描述】:

要么我错过了一些反冲,要么反冲似乎不适用于过多的程序员引用循环。

$ echo "hello1-`echo hello2-\`echo hello3-\`echo hello4\`\``"

hello1-hello2-hello3-echo hello4

通缉

hello1-hello2-hello3-hello4-hello5-hello6-...

【问题讨论】:

  • 这个问题应该是“如何递归地使用 Bash 反引号”。这应该可以帮助 Google 员工。
  • 你想做什么。?这根本没有任何意义。
  • @joey,标题已更改,欢迎您:D
  • 糟糕,从头开始。它应该是“如何在 bash 中嵌套反引号?” .我把递归和嵌套搞混了。
  • 反引号是deprecated,因此使用$(cmd)

标签: bash shell unix quoting


【解决方案1】:

您可以增量捕获并组合成一个变量

__=`printf hello2-`
__=`printf "${__}hello3-"`
__=`printf "${__}hello4-"`
printf "hello1-${__}"

【讨论】:

    【解决方案2】:

    有时反引号嵌套可以替换为xargs 和管道

    $ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1
    hello1 hello2 hello3 hello4
    

    此解决方案的缺点是:

    • 所有参数必须以相反的顺序提供 (4→1);
    • 所有参数都以空格分隔(可使用tr 解决):

      $ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1 | tr ' ' '-'
      hello1-hello2-hello3-hello4
      


    让我们展示一个真实的用例。

    以下命令在 bash 中有效,但在 tcsh 中无效(反引号嵌套在 tcsh 中处理得不是很好)

    $ ls $(dirname $(which bash))
    $ ls `dirname \`which bash\``
    

    它们可以替换为

    $ which bash | xargs dirname | xargs ls
    

    【讨论】:

    • 这种xargs 解决方法在您遇到sh 时非常方便,例如在Makefile 命令中。
    【解决方案3】:

    任何时候你想评估一个命令使用command substitution:

    $(command)
    

    任何时候你想计算一个算术表达式,使用expression substitution

    $((expr))
    

    你可以这样嵌套:

    假设 file1.txt 有 30 行长,而 file2.txt 有 10 行长,那么您可以像这样计算表达式:

    $(( $(wc -l file1.txt) - $(wc -l file2.txt) ))
    

    这将输出 20(两个文件之间的行数差异)。

    【讨论】:

      【解决方案4】:

      如果您坚持使用反引号,则可以进行以下操作

      $ echo "hello1-`echo hello2-\`echo hello3-\\\`echo hello4\\\`\``"
      

      你必须把反斜杠,\\ \\\\ \\\\\\\\ 加 2x 等等,它只是非常丑陋,使用 $(commands) 作为其他建议。

      【讨论】:

        【解决方案5】:

        改用$(commands)

        $ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
        hello1-hello2-hello3-hello4
        

        $(commands) 与反引号的作用相同,但您可以嵌套它们。

        您可能还对 Bash 范围扩展感兴趣:

        echo hello{1..10}
        hello1 hello2 hello3 hello4 hello5 hello6 hello7 hello8 hello9 hello10
        

        【讨论】:

        • +1 喜欢 {1..10}。用数组限制它? ZSH 可以“${$(date)[2,4]}”。为什么不:“echo ${echo hello1-$(echo hello2)[1]}”?
        • 不是所有的shell都支持$()
        • @CervEd 只是好奇,您使用的是什么系统和外壳?在 Ubuntu 上,即使是默认的“sh”(破折号)也支持美元符号并嵌套它。
        • @JoeyAdams 我使用支持$() 的shell,并且AFAIK 大多数shell 都支持它,但不是全部。 Solaris sh 似乎没有。
        【解决方案6】:

        如果你使用bash的$(cmd)command substitution syntax会容易很多,对嵌套更友好:

        $ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
        hello1-hello2-hello3-hello4
        

        【讨论】:

        • 这不限于 bash。它适用于所有符合 POSIX 1003.1(“POSIX shell”)的 shell 和大多数 Bourne 派生的 shell(kshashdashbashzsh 等)虽然不是实际的 Bourne shell(即heirloom.sourceforge.net/sh.html)。
        • 哇,这个答案的时间戳与@joey_adams 的答案相同!最字面意思的同步性:)在这里也赞成(:
        猜你喜欢
        • 1970-01-01
        • 2011-09-30
        • 2018-05-07
        • 2013-09-23
        • 1970-01-01
        • 2014-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多