Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash Can';t出口和t形三通执行的奇怪顺序_Bash_Tee_Zsh - Fatal编程技术网

Bash Can';t出口和t形三通执行的奇怪顺序

Bash Can';t出口和t形三通执行的奇怪顺序,bash,tee,zsh,Bash,Tee,Zsh,将函数的输出管道化到tee命令时,我遇到了一些奇怪的行为。第一个问题是,当从管道传输到tee的函数调用exit命令时,我无法退出程序。例如: myfunction(){ # Some stuff here exit 1 } myfunction | tee -a $UPGRADE_LOG 当我运行上述代码时,程序无法退出并运行到完成 我遇到的另一个问题是,tee似乎导致一些代码以这样的方式运行,顺序被撤消。我有以下输出: 显示系统范围和INSTATNCE内存使用情况: 您确定

将函数的输出管道化到
tee
命令时,我遇到了一些奇怪的行为。第一个问题是,当从管道传输到
tee
的函数调用
exit
命令时,我无法退出程序。例如:

myfunction(){
    # Some stuff here
    exit 1
}

myfunction | tee -a $UPGRADE_LOG
当我运行上述代码时,程序无法退出并运行到完成

我遇到的另一个问题是,
tee
似乎导致一些代码以这样的方式运行,顺序被撤消。我有以下输出:

显示系统范围和INSTATNCE内存使用情况:
您确定要备份给定当前内存限制的实例吗?[y/n]:已使用的文件系统大小可用率已安装%
/dev/mapper/system root 15G 13G 1.5G 90%/
日志文件大小:24K包的总大小:248K可用空间:1.5G
它应该在什么时候运行:

显示系统范围和INSTATNCE内存使用情况:
已使用的文件系统大小可用已安装的文件系统%
/dev/mapper/system root 15G 13G 1.5G 90%/
日志文件大小:24K包的总大小:248K可用空间:1.5G
您确定要备份给定当前内存限制的实例吗?[是/否]:

不使用
tee
时,一切正常。这些问题似乎相互关联。你知道为什么会这样吗?我应该怎么做?

这个
exit
语句退出进程运行的(子)shell。现在惊喜来了:

管道

管道是由一个控制操作符
|
|&
分隔的一个或多个命令的序列。管道的格式为:

[time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]

管道中的每个命令都作为单独的进程执行(即在子shell中)。

来源:
manbash

因此,函数中的
exit
语句只会终止管道的子shell。这实际上意味着
exit
在管道中什么都不做

$ exit | exit | echo foo
foo
$ exit | exit
$ # shell not terminated
注意:这显然取决于shell,因为行为不同。

告诉您为什么会发生这种情况。这一个告诉您如何修复它。:)

这里重要的是,我们不是使用常规管道,而是使用for
tee
——因此
myfunction
在shell本身而不是子shell中运行,因此
退出
正确应用



至于为什么通过
tee
重定向stdout会取消stderr的同步,请参见请不要问多个问题,而是将它们分开。还要注意的是,如果你尽可能接近MCVE,你会增加获得好答案的机会:这些问题似乎与同一个问题有关,所以我把它们放在一起。很抱歉,如果它带来了任何混乱。不,代码不是非顺序运行的——所发生的是,您的stdout和stderr正在经历不同的进程,因此它们在不同的时间到达。不过,最初的写操作仍然是同时进行的。是的,我知道代码是按顺序运行的。我只是指出它的表现就是这样。我认为这是因为它们是分开运行的,我只是不知道为什么。谢谢你的澄清!“什么都不做”不是很准确
exit 2 | exit 3 | true
${PIPESTATUS[0]}
设置为2和
${PIPESTATUS[1]}
设置为3,如果
set-o pipefail
处于活动状态,则会导致整个管道的退出状态为3。尽管如此,这些效果并不是OP想要的@查理·达菲是真的。此外,如果设置了选项
lastpipe
,它将对最后一个
exit
语句产生影响(例如
exit | exit
),此解决方案工作正常。谢谢你的解释!
with_logs_piped() {
  local logfile=$1; 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