代码之家  ›  专栏  ›  技术社区  ›  markcial

如何将输出重定向到shell中的变量?[副本]

  •  162
  • markcial  · 技术社区  · 14 年前

    这个问题已经有了答案:

    我有这样的剧本

    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 回复  |  直到 6 年前
        1
  •  285
  •   anon    14 年前

    使用 $( ... ) 构造:

    hash=$(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)
    
        2
  •  168
  •   Bruno Bronosky    6 年前

    存储 "abc" 进入之内 $foo :

    echo "abc" | read foo
    

    但是,因为管道会产生分叉,所以必须使用 $FO 在管道末端之前,所以…

    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 精氨酸 因此,它必须作为一个变量出现。该命令输出修改后的内容,通常会被重定向到一个文件或通过管道传输到另一个命令。(例如) sed , awk , perl 等等)

    3. 阅读 获取stdin并将其放入变量 $string

    4. 阅读 以及 神秘指挥部 通过圆括号进入“子shell”是不必要的,但使它像一个连续的管道一样流动,就像两个命令在单独的脚本文件中一样。

    总有一个选择,在这种情况下,与我上面的例子相比,这个选择是丑陋的和不可读的。

    # 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魔法。

        3
  •  46
  •   Bruno Bronosky    7 年前
    read hash < <(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)
    

    这种技术使用bash的 process substitution “不要混淆” command substitution “。

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

        4
  •  16
  •   ony    14 年前

    我想兼容的方式是:

    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)"
    
        5
  •  4
  •   Noldorin    8 年前

    如果管道太复杂,无法包装 $(...) ,考虑编写函数。定义时可用的任何局部变量都将是可访问的。

    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

        6
  •  2
  •   codaddict    14 年前

    你可以这样做:

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

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

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

        7
  •  1
  •   Arena Hernandez    6 年前

    创建一个函数,将其作为要调用的命令来调用。在这种情况下,我需要使用 鲁克 命令。

    然后,调用函数并将其结果赋给变量。在这种情况下,我将结果赋给变量 健康 .

    function ruok {
      echo ruok | nc *ip* 2181
    }
    
    health=echo ruok *ip*
    
        8
  •  0
  •   Community datashaman    7 年前

    使用时有时会出错 $(`code`) 建造师。

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

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

    不是吗?我想您当前的任务genhash将只输出一个字符串hash,所以可能对您有用。

    我是如此的neewbie,仍然在寻找完整的输出&save into 1命令。 当做。