【问题标题】:bash shell script - getting a string from the console and store it into a variablebash shell 脚本 - 从控制台获取字符串并将其存储到变量中
【发布时间】:2017-09-22 08:11:51
【问题描述】:

我正在执行一些从控制台生成字符串的操作,例如我正在执行以下操作:

./eqagent add-target target-type=kafka events-servers=localhost:9999

并收到此消息:

Equalum 代理返回以下错误:代理目标 已经存在

我想捕获它并将其存储到一个变量中,然后使用 if 语句将其用作条件。

【问题讨论】:

    标签: bash shell scripting


    【解决方案1】:

    试试这个:

    message=$(./eqagent add-target target-type=kafka events-servers=localhost:9999 2>&1)
    

    varname=$(some command) 语法称为命令替换,并扩展为括号内包含的命令生成的字符串。

    2>&1 部分是一个重定向,它采用文件描述符 2 的输出(通常称为“标准错误”)并使其转到与文件描述符 1 相同的输出(通常称为“标准输出” )。这可以确保您的进程替换将收集两者的输出,因为命令替换只捕获标准输出,而不是标准错误。

    如果你只是想测试成功失败,你可以使用命令的返回码,像这样:

    if
      ./eqagent add-target target-type=kafka events-servers=localhost:9999 2>&1
    then
      # Success!
    else
      # Failure...
    fi
    

    如果在命令执行后立即调用,返回码也可以在特殊的 shell 变量 $? 中获得,并且 vy 约定成功时为零,失败时为非零值。

    【讨论】:

      【解决方案2】:

      在我看来,您的问题就像一个典型的X-Y problem:您的问题是您想在命令失败时采取行动,而当这种情况发生时,它会将返回值设置为非零值。所以你真正想要的是使用$? 变量。这是您的用例的一般示例:

      $ ./command
      Argh... Failure!
      $ echo $?
      1
      

      所以你可以这样做:

      if [ $? -eq 1 ]; then
          echo "It failed :("
      fi
      

      您可能有多个返回值来描述错误,因此您可以检查等于23255 的值。

      但是您的 shell 允许您以更简洁的方式做到这一点:

      # prints 'it failed :(' only when command's result ($?) is non-null
      ./command || echo "it failed :("
      

      所以对于您的示例,您应该能够使用:

      ./eqagent add-target target-type=kafka events-servers=localhost:9999 || echo "it failed :("
      

      如果您的命令真的只使用字符串返回错误状态(不是很好),您可以使用以下命令检查 exact 字符串:

      output=$(./eqagent add-target target-type=kafka events-servers=localhost:9999)
      if [ "$output" == "Equalum agent has returned the following error: The agent target already exists" ]; then
          echo "it failed :("
      fi
      

      最后你可以检查是否包含子字符串(如果这不是你的程序的唯一输出):

      error_msg="The agent target already exists"
      if [ -z "${output##*$error_msg*}" ] ;then
          echo "it failed :("
      fi
      

      上述语法适用于大多数 shell(bash、ksh、dash…)。

      如果您在 $output 变量中没有得到您期望的输出,这很可能是程序在 stderr 而不是 stdout 上打印错误,您可以使用以下技巧连接两个输出:

      output=$(./eqagent add-target target-type=kafka events-servers=localhost:9999 2>&1)
      

      最后在实际用例中,您可能需要两者的混合:

      error_msg="The agent target already exists"
      output=$(./eqagent add-target target-type=kafka events-servers=localhost:9999)
      if [ $? -ne 0 ]; then
          echo -n "it failed "
          if [ -z "${output##*$error_msg*}" ] ;then
              echo "; because target already exists. :-s"
          else
              echo ":-("
          fi
      fi
      

      【讨论】:

      • if [ ! $? -eq 0]; then 将失败,因为“0”后面没有空格。另外为什么不改用if [ $? -ne 0 ]? -ne = 不等于
      • 第一个是错字,第二个是没有充分理由的,因为这是我的手指写的 ☺ 都更正了,谢谢。
      • 另外,output=$(./eqagent add-target target-type=kafka events-servers=localhost:9999) 不会捕获任何错误消息(假设错误消息被发送到 stderr),您也应该捕获它
      • 已经在 In case you don't get the output you expect in the $output variable, which is likely if the program prints error on stderr instead of stdout, you can join both outputs 部分介绍了?
      【解决方案3】:

      你不能这样做吗:

      variable=`your-command`
      

      然后使用 $variable 做任何你想做的事情

      【讨论】:

        【解决方案4】:
        var="$((./eqagent add-target target-type=kafka events-servers=localhost:9999)2>&1)" # We must also make sure that stderr goes into stdin so we can capture the error message. That is what 2>&1 does
        if [ $? -ne 0 ];then # Eg, it failed
            echo "the output is stored in '$var'." 
            echo "$var" > error_log.txt
        fi
        

        这应该可以解决问题

        编辑:忘记添加标准错误重定向...

        【讨论】:

        • 括号的内部集没有用,因为您无用地生成了一个额外的外壳,并且与管道重定向无关。
        猜你喜欢
        • 1970-01-01
        • 2019-03-18
        • 1970-01-01
        • 2020-08-11
        • 1970-01-01
        • 2016-07-10
        • 2018-11-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多