Chinaunix
标题:
SHELL中如何获得管道前面的命令的返回值?
[打印本页]
作者:
xuphys
时间:
2011-01-25 10:14
标题:
SHELL中如何获得管道前面的命令的返回值?
SHELL中如何获得管道前面的命令的返回值?
bash中可以用PIPESTATUS,但是其他的shell呢?
谢谢。
作者:
南极雨
时间:
2011-01-25 10:42
本帖最后由 南极雨 于 2011-01-25 10:43 编辑
好像其他的shell也都支持这个pip吧...
windows下的powershell 用的不多,不太清楚!
作者:
xuphys
时间:
2011-01-25 11:35
powershell貌似不行,不过我不关心。我想知道其他的UNIX shell是否支持呢?
作者:
xuphys
时间:
2011-01-25 11:36
ksh好像就没有。。。
作者:
cjaizss
时间:
2011-01-25 13:11
其他shell没有很正常
作者:
ly5066113
时间:
2011-01-25 13:14
comp.unix.shell FAQ(转载http://home.comcast.net/~j.p.h/)
11. How do I get the exit code of cmd1 in cmd1|cmd2
First, note that cmd1 exit code could be non-zero and still don't
mean an error. This happens for instance in
cmd | head -1
you might observe a 141 (or 269 with ksh93) exit status of cmd1,
but it's because cmd was interrupted by a SIGPIPE signal when
"head -1" terminated after having read one line.
To know the exit status of the elements of a pipeline
cmd1 | cmd2 | cmd3
a. with zsh:
The exit codes are provided in the pipestatus special array.
cmd1 exit code is in $pipestatus[1], cmd3 exit code in
$pipestatus[3], so that $? is always the same as
$pipestatus[-1].
b. with bash:
The exit codes are provided in the PIPESTATUS special array.
cmd1 exit code is in ${PIPESTATUS[0]}, cmd3 exit code in
${PIPESTATUS[2]}, so that $? is always the same as
${PIPESTATUS: -1}.
c. with any other Bourne like shells
You need to use a trick to pass the exit codes to the main
shell. You can do it using a pipe(2). Instead of running
"cmd1", you run "cmd1; echo $?" and make sure $? makes it way
to the shell.
exec 3>&1
eval `
# now, inside the `...`, fd4 goes to the pipe
# whose other end is read and passed to eval;
# fd1 is the normal standard output preserved
# the line before with exec 3>&1
exec 4>&1 >&3 3>&-
{
cmd1 4>&-; echo "ec1=$?;" >&4
} | {
cmd2 4>&-; echo "ec2=$?;" >&4
} | cmd3
echo "ec3=$?;" >&4
`
d. with a POSIX shell
You can use this function to make it easier:
run() {
j=1
while eval "\${pipestatus_$j+:} false"; do
unset pipestatus_$j
j=$(($j+1))
done
j=1 com= k=1 l=
for a; do
if [ "x$a" = 'x|' ]; then
com="$com { $l "'3>&-
echo "pipestatus_'$j'=$?" >&3
} 4>&- |'
j=$(($j+1)) l=
else
l="$l \"\$$k\""
fi
k=$(($k+1))
done
com="$com $l"' 3>&- >&4 4>&-
echo "pipestatus_'$j'=$?"'
exec 4>&1
eval "$(exec 3>&1; eval "$com")"
exec 4>&-
j=1
while eval "\${pipestatus_$j+:} false"; do
eval "[ \$pipestatus_$j -eq 0 ]" || return 1
j=$(($j+1))
done
return 0
}
use it as:
run cmd1 \| cmd2 \| cmd3
exit codes are in $pipestatus_1, $pipestatus_2, $pipestatus_3
复制代码
作者:
cjaizss
时间:
2011-01-25 13:33
ly5066113 发表于 2011-01-25 13:14
呵呵,办法总是人想的
作者:
xuphys
时间:
2011-02-03 17:08
似乎只能用很麻烦的的方法了
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2