在 bash 中,如何从由 tee 传输的函数中退出脚本?
In bash how do I exit a script from a function that is piped by tee?
我试图理解为什么每当我使用 function 2>&1 | tee -a $LOG
tee 时都会在函数中创建一个无法通过简单 exit 1
退出的子外壳(如果我不使用 tee
它工作正常)。下面的例子:
#!/bin/bash
LOG=/root/log.log
function first()
{
echo "Function 1 - I WANT to see this."
exit 1
}
function second()
{
echo "Function 2 - I DON'T WANT to see this."
exit 1
}
first 2>&1 | tee -a $LOG
second 2>&1 | tee -a $LOG
输出:
[root@linuxbox ~]# ./1.sh
Function 1 - I WANT to see this.
Function 2 - I DON'T WANT to see this.
所以。如果我删除 | tee -a $LOG
部分,它将按预期工作(脚本将在第一个函数中退出)。
能否请您解释一下如何克服这个问题并在函数中正确退出,同时能够输出 tee?
如果你创建一个管道,函数是 运行 在子shell,如果你 exit
来自子shell,只有子shell 会受到影响,而不是父级 shell。
printPid(){ echo $BASHPID; }
printPid #some value
printPid #same value
printPid | tee #an implicit subshell -- different value
( printPid ) #an explicit subshell -- also a different value
如果您不选择 aFunction | tee
:
aFunction > >(tee)
基本相同,除了 aFunction
不会 运行 在子 shell 中,因此将能够影响当前环境(设置变量,调用退出等)。
如果管道中的任何内容失败,您可以告诉 bash 失败 set -e -o pipefail
:
$ cat test.sh
#!/bin/bash
LOG=~/log.log
set -e -o pipefail
function first()
{
echo "Function 1 - I WANT to see this."
exit 1
}
function second()
{
echo "Function 2 - I DON'T WANT to see this."
exit 1
}
first 2>&1 | tee -a $LOG
second 2>&1 | tee -a $LOG
$ ./test.sh
Function 1 - I WANT to see this.
使用PIPESTATUS
检索管道中第一个命令的退出状态。
first 2>&1 | tee -a $LOG; test ${PIPESTATUS[0]} -eq 0 || exit ${PIPESTATUS[0]}
second 2>&1 | tee -a $LOG; test ${PIPESTATUS[0]} -eq 0 || exit ${PIPESTATUS[0]}
我试图理解为什么每当我使用 function 2>&1 | tee -a $LOG
tee 时都会在函数中创建一个无法通过简单 exit 1
退出的子外壳(如果我不使用 tee
它工作正常)。下面的例子:
#!/bin/bash
LOG=/root/log.log
function first()
{
echo "Function 1 - I WANT to see this."
exit 1
}
function second()
{
echo "Function 2 - I DON'T WANT to see this."
exit 1
}
first 2>&1 | tee -a $LOG
second 2>&1 | tee -a $LOG
输出:
[root@linuxbox ~]# ./1.sh
Function 1 - I WANT to see this.
Function 2 - I DON'T WANT to see this.
所以。如果我删除 | tee -a $LOG
部分,它将按预期工作(脚本将在第一个函数中退出)。
能否请您解释一下如何克服这个问题并在函数中正确退出,同时能够输出 tee?
如果你创建一个管道,函数是 运行 在子shell,如果你 exit
来自子shell,只有子shell 会受到影响,而不是父级 shell。
printPid(){ echo $BASHPID; }
printPid #some value
printPid #same value
printPid | tee #an implicit subshell -- different value
( printPid ) #an explicit subshell -- also a different value
如果您不选择 aFunction | tee
:
aFunction > >(tee)
基本相同,除了 aFunction
不会 运行 在子 shell 中,因此将能够影响当前环境(设置变量,调用退出等)。
如果管道中的任何内容失败,您可以告诉 bash 失败 set -e -o pipefail
:
$ cat test.sh
#!/bin/bash
LOG=~/log.log
set -e -o pipefail
function first()
{
echo "Function 1 - I WANT to see this."
exit 1
}
function second()
{
echo "Function 2 - I DON'T WANT to see this."
exit 1
}
first 2>&1 | tee -a $LOG
second 2>&1 | tee -a $LOG
$ ./test.sh
Function 1 - I WANT to see this.
使用PIPESTATUS
检索管道中第一个命令的退出状态。
first 2>&1 | tee -a $LOG; test ${PIPESTATUS[0]} -eq 0 || exit ${PIPESTATUS[0]}
second 2>&1 | tee -a $LOG; test ${PIPESTATUS[0]} -eq 0 || exit ${PIPESTATUS[0]}