无法使用 tee 退出和奇怪的执行顺序
Can't exit and strange order of execution with tee
将函数的输出通过管道传送到 tee
命令时,我遇到了一些奇怪的行为。第一个问题是,当从管道传送到 tee
的函数调用时,我无法使用 exit
命令退出程序。例如:
myfunction(){
# Some stuff here
exit 1
}
myfunction | tee -a $UPGRADE_LOG
当我运行上述代码时,程序无法退出并运行s完成。
我遇到的另一个问题是 tee
似乎导致某些代码以 运行 的方式取消顺序。我有以下输出:
SHOWING SYSTEM-WIDE AND INSTATNCE MEMORY USAGE:
Are you sure you would like to back up the instance given current memory contraints? [y/n]: Filesystem Size Used Avail Use% Mounted on
/dev/mapper/system-root 15G 13G 1.5G 90% /
Log File Size: 24K Total Size to Package: 248K Available Space: 1.5G
什么时候应该 运行 为:
SHOWING SYSTEM-WIDE AND INSTATNCE MEMORY USAGE:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/system-root 15G 13G 1.5G 90% /
Log File Size: 24K Total Size to Package: 248K Available Space: 1.5G
Are you sure you would like to back up the instance given current memory contraints? [y/n]:
不使用 tee
时一切正常。这些问题似乎彼此相关。知道为什么会这样吗?我应该怎么做?
exit
语句退出(sub-)shell进程在运行中。现在惊喜来了:
Pipelines
A pipeline is a sequence of one or more commands separated by one of the control operators |
or |&
. The format for a pipeline is:
[time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]
<snip>
Each command in a pipeline is executed as a separate process (i.e., in a subshell).
source: man bash
因此,函数中的 exit
语句只是终止了管道的子 shell。这实际上意味着 exit
在管道中什么都不做
$ exit | exit | echo foo
foo
$ exit | exit
$ # shell not terminated
注意: 这显然是 shell 相关的,因为 zsh 的行为不同。
告诉你为什么会这样。这个告诉你如何修复它。 :)
with_logs_piped() {
local logfile=; shift
"$@" > >(tee -a -- "$logfile") 2>&1 # 2>&1 redirects stderr through the same tee so it's
} # ...also logged, and shows up sync'd with stdout.
myfunction() {
# Some stuff here
exit 1
}
with_logs_piped "$UPGRADE_LOG" myfunction
这里重要的是,我们没有使用常规管道,而是为 tee
使用 process substitution——因此 myfunction
在您的 shell 本身中运行, 不是 subshell,所以 exit
适用。
至于为什么通过 tee
重定向 stdout 会使 stderr 不同步,请参阅
将函数的输出通过管道传送到 tee
命令时,我遇到了一些奇怪的行为。第一个问题是,当从管道传送到 tee
的函数调用时,我无法使用 exit
命令退出程序。例如:
myfunction(){
# Some stuff here
exit 1
}
myfunction | tee -a $UPGRADE_LOG
当我运行上述代码时,程序无法退出并运行s完成。
我遇到的另一个问题是 tee
似乎导致某些代码以 运行 的方式取消顺序。我有以下输出:
SHOWING SYSTEM-WIDE AND INSTATNCE MEMORY USAGE:
Are you sure you would like to back up the instance given current memory contraints? [y/n]: Filesystem Size Used Avail Use% Mounted on
/dev/mapper/system-root 15G 13G 1.5G 90% /
Log File Size: 24K Total Size to Package: 248K Available Space: 1.5G
什么时候应该 运行 为:
SHOWING SYSTEM-WIDE AND INSTATNCE MEMORY USAGE:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/system-root 15G 13G 1.5G 90% /
Log File Size: 24K Total Size to Package: 248K Available Space: 1.5G
Are you sure you would like to back up the instance given current memory contraints? [y/n]:
不使用 tee
时一切正常。这些问题似乎彼此相关。知道为什么会这样吗?我应该怎么做?
exit
语句退出(sub-)shell进程在运行中。现在惊喜来了:
Pipelines
A pipeline is a sequence of one or more commands separated by one of the control operators
|
or|&
. The format for a pipeline is:[time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]
<snip>
Each command in a pipeline is executed as a separate process (i.e., in a subshell).
source:
man bash
因此,函数中的 exit
语句只是终止了管道的子 shell。这实际上意味着 exit
在管道中什么都不做
$ exit | exit | echo foo
foo
$ exit | exit
$ # shell not terminated
注意: 这显然是 shell 相关的,因为 zsh 的行为不同。
with_logs_piped() {
local logfile=; shift
"$@" > >(tee -a -- "$logfile") 2>&1 # 2>&1 redirects stderr through the same tee so it's
} # ...also logged, and shows up sync'd with stdout.
myfunction() {
# Some stuff here
exit 1
}
with_logs_piped "$UPGRADE_LOG" myfunction
这里重要的是,我们没有使用常规管道,而是为 tee
使用 process substitution——因此 myfunction
在您的 shell 本身中运行, 不是 subshell,所以 exit
适用。
至于为什么通过 tee
重定向 stdout 会使 stderr 不同步,请参阅