【问题标题】:Shell script not exiting after a pipe to log file command管道记录文件命令后,Shell 脚本未退出
【发布时间】:2014-02-06 12:33:30
【问题描述】:

请找到下面的脚本。 当我运行它时, ./myscript.sh 我在终端和我的日志文件中得到所有的 echo 语句。 但执行后它没有退出或返回终端 请帮忙。我对脚本很陌生。

#!/bin/sh

process() {
echo "Start..."
echo "Stop..."
exit 10
}

until [ $? -eq 10 ];
do
process | tee -a /home/temp/myLog.log
done

【问题讨论】:

    标签: linux bash shell pipe exit


    【解决方案1】:

    管道的退出代码是管道中最后一个进程的退出代码。所以在这里,即使process 以代码 10 退出,整个管道 process | tee ... 也会以代码 0 退出。

    您可以使用 pipefail 选项更改此行为

    set -o pipefail
    

    现在管道的退出代码将是任何管道进程的最后一个非零退出代码,如果它们都成功退出,则为 0。

    This blog post很好解释,官方参考是this section of the Bash manual的最后一段。

    【讨论】:

      【解决方案2】:

      尝试使用 ${PIPESTATUS[0]} 获取管道第一部分的结果:

      #!/bin/sh
      
      process() {
      echo "Start..."
      echo "Stop..."
      exit 10
      }
      
      result=0
      until [ $result -eq 10 ]
      do
         process | tee -a myLog.log
         result=${PIPESTATUS[0]}
         echo $result
      done
      

      【讨论】:

      • 那不是bash 特定的吗?
      【解决方案3】:

      将管道移到循环后面;结果是一样的,但破坏会起作用:

      #!/bin/sh
      
      process() {
        echo "Start..."
        echo "Stop..."
        exit 10
      }
      
      until [ $? -eq 10 ]
      do
        process
      done | tee -a /home/temp/myLog.log
      

      正如其他人在我之前指出的那样,管道的退出状态很复杂,所以你不能只使用$? 来获取它。最好的解决方案似乎是在需要退出状态的上下文中摆脱管道。

      也许你甚至不再需要 -a 这种方式了。

      【讨论】:

      • @rishimon 我也试过了,它就像一个魅力:) 不,老实说,什么“不出来”?脚本没有退出循环吗?输出没有进入日志文件吗?相反,你观察到了什么?
      猜你喜欢
      • 2018-05-27
      • 1970-01-01
      • 2017-08-15
      • 2013-03-01
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      相关资源
      最近更新 更多