【问题标题】:bash -- setting multiple variables in a single pipeline stagebash -- 在单个管道阶段设置多个变量
【发布时间】:2018-12-06 21:06:15
【问题描述】:

我希望做类似的事情:

echo 1 2 | read foo bar

将两个新变量 foo 和 bar 分别设置为值 1 和 2。 (实际上,“echo 1 2”将是对外部数据源的 awk / cut 调用。)

我发现 foo 和 bar 在此行之后不存在,这让我想知道这是否是范围问题?我只在 while 循环中使用了 read,在这些情况下,循环体能够访问变量。

【问题讨论】:

  • 管道强制另一个子外壳,因此变量丢失。
  • 如果你真的使用echo 1 2,只需写foo=1 bar=2 ...。如果您使用 echo 作为简化示例,请不要介意。

标签: bash shell scripting


【解决方案1】:

管道在子外壳中执行。因此,变量foobar 被创建,1 和2 被存储在其中,然后子shell 退出并返回到不存在这些变量的父shell。

read 转换为您想要的变量的一种方法是使用“here string

read foo bar <<<"1 2"

这将执行您期望管道版本执行的操作。

但是,这是不可移植的,并且某些 shell 不支持它。您可以改用“here document”表单,该表单已得到广泛支持。

$ read foo bar <<EOF
> 1 2
> EOF

注意这里的EOF 可以是任何唯一的字符串。此处的文档将存储所有行,直到包含 EOF 或您选择的任何标记的行,仅此而已。在这种情况下,行为也与前面的示例相同(但更难复制和粘贴,并且输入时间更长)。

这是怎么回事?

“here 文档”和“here 字符串”都是表示传递给标准输入的文本的方式,而无需以交互方式输入。在功能上相当于只说read foo bar,按回车,然后手动写1 2,再按回车。

【讨论】:

  • 感谢您解释 Sorpigal。这里的字符串想法会为我解决问题,谢谢。
  • 很好的解释,也感谢您指出可移植性问题。
  • 我使用了一个反引号中包含我的处理命令的heredoc,即一个包含shellout的heredoc。
【解决方案2】:

你可以做这样的事情,而不是管道 -

[jaypal:~/Temp] exec 3< <(echo "Jaypal Singh")
[jaypal:~/Temp] while read word1 word2 ; do echo "$word1 $word2"; done <&3
Jaypal Singh

[jaypal:~/Temp] exec 3< <(echo "Jaypal Singh")
[jaypal:~/Temp] while read word1 word2 ; do echo "$word1"; done <&3
Jaypal

【讨论】:

    【解决方案3】:

    另一个简单的解决方案 - 在某些情况下它可能有用:

    echo 1 2 | { read foo bar; echo $foo $bar; }
    

    当然,就像原来的问题一样,echo 命令可能会有更复杂的处理。

    【讨论】:

      【解决方案4】:

      感谢 bash 在管道时运行子 shell,现在我们不能同时读取多个变量了!

      grep -w 正则表达式文件 |读取 var1 var2 var3

      没有替代此 KSH 功能的解决方案。解决办法:

      '读取

      【讨论】:

        猜你喜欢
        • 2021-10-10
        • 1970-01-01
        • 2020-06-10
        • 2021-11-16
        • 1970-01-01
        • 1970-01-01
        • 2021-03-25
        • 1970-01-01
        • 2020-03-29
        相关资源
        最近更新 更多