如何将输出重定向到shell中的变量?

时间:2010-04-01 08:33:17

标签: bash shell

我有一个类似的脚本

genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5

我想在变量中获取genhash生成的流。如何将其重定向到变量$hash以在条件内进行比较?

if [ $hash -ne 0 ]
  then echo KO
  exit 0
else echo -n OK
  exit 0
fi

8 个答案:

答案 0 :(得分:298)

使用$( ... )构造:

hash=$(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)

答案 1 :(得分:181)

<强> TL; DR

"abc"存储到$foo

echo "abc" | read foo

但是,因为管道会产生分叉,所以在管道结束之前必须使用$foo,所以......

echo "abc" | ( read foo; date +"I received $foo on %D"; )

当然,所有这些其他答案都显示了不做OP所要求的方法,但这确实搞砸了我们其他寻找OP问题的人。

问题的答案是使用 read 命令。

这是你如何做的

# I would usually do this on one line, but for readability...
series | of | commands \
| \
(
  read string;
  mystic_command --opt "$string" /path/to/file
) \
| \
handle_mystified_file

这是它正在做什么以及为什么它很重要:

  1. 让我们假装series | of | commands是一系列非常复杂的管道命令。

  2. mystic_command可以接受文件内容作为stdin而不是文件路径,但不是--opt arg 因此它必须作为变量。该命令输出修改后的内容,通常会重定向到文件或管道传输到另一个命令。 (例如sedawkperl等。

  3. read接受标准输入并将其放入变量$string

  4. 通过括号将readmystic_command放入“子shell”中是不必要的,但会使其像连续管道一样流动,就像2个命令在单独的脚本文件中一样

  5. 总有一种替代方案,在这种情况下,与上面的例子相比,替代方案是丑陋且难以理解的。

    # my example above as a oneliner
    series | of | commands | (read string; mystic_command --opt "$string" /path/to/file) | handle_mystified_file
    
    # ugly and unreadable alternative
    mystic_command --opt "$(series | of | commands)" /path/to/file | handle_mystified_file
    

    我的方式完全是按时间顺序和逻辑。替代方案从第4个命令开始,并将命令1,2和3推送到命令替换中。

    我在this script中有一个真实世界的例子,但我并没有将它作为上面的例子,因为它还有一些其他疯狂/混乱/分散注意力的bash魔法。

答案 2 :(得分:49)

read hash < <(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)

此技术使用Bash的“process substitution”不要与“command substitution”混淆。

以下是一些很好的参考资料:

答案 3 :(得分:16)

我想兼容的方式:

hash=`genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5`

但我更喜欢

hash="$(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)"

答案 4 :(得分:4)

如果管道太复杂而无法包裹$(...),请考虑编写一个函数。可以访问定义时可用的任何局部变量。

function getHash {
  genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5
}
hash=$(getHash)

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Functions

答案 5 :(得分:3)

你可以这样做:

hash=$(genhash --use-ssl -s $IP -p 443 --url $URL)

hash=`genhash --use-ssl -s $IP -p 443 --url $URL`

如果要将整个管道的结果分配给变量,可以在上述分配中使用整个管道。

答案 6 :(得分:1)

创建一个函数调用它作为您要调用的命令。在这种情况下,我需要使用 ruok 命令。

然后,调用函数并将其结果分配给变量。在这种情况下,我将结果分配给变量 health

function ruok {
  echo ruok | nc *ip* 2181
}

health=echo ruok *ip*

答案 7 :(得分:0)

使用$(`code`)构造函数时,我有时会收到错误。

最后我在这里得到了一些方法:https://stackoverflow.com/a/7902174/2480481

基本上,使用Tee再次读取输出并将其放入变量中。 你是如何看到正常输出然后从输出读取它。

不是吗?我猜你当前的任务genhash会输出那个,单个字符串哈希所以可能适合你。

我是neewbie,仍然在寻找完整的输出和放大器保存为1个命令。 问候。