我是 linux 和 bash 脚本的新手,我对这个内部变量 PIPESTATUS 有疑问,它是一个数组,将各个命令的退出状态存储在管道中。
在命令行上:
$ find /home | /bin/pax -dwx ustar | /bin/gzip -c > myfile.tar.gz
$ echo ${PIPESTATUS[*]}
$ 0 0 0
在命令行上工作正常,但是当我将此代码放入 bash 脚本时,它只显示一个退出状态。我在命令行上的默认 SHELL 仅是 bash。
有人请帮我理解为什么这种行为正在改变?我应该怎么做才能在脚本中完成这项工作?
#!/bin/bash
cmdfile=/var/tmp/cmd$$
backfile=/var/tmp/backup$$
find_fun() {
find /home
}
cmd1="find_fun | /bin/pax -dwx ustar"
cmd2="/bin/gzip -c"
eval "$cmd1 | $cmd2 > $backfile.tar.gz " 2>/dev/null
echo -e " find ${PIPESTATUS[0]} \npax ${PIPESTATUS[1]} \ncompress ${PIPESTATUS[2]} > $cmdfile
最佳答案
您的脚本存在的问题是您没有运行与在命令行上运行的代码相同的代码。您正在运行不同 代码。即脚本添加了eval
。如果您将命令行测试包装在 eval
中,您会发现它以类似的方式失败。
eval
版本失败的原因(只在 PIPESTATUS
中给您一个值)是因为您不再执行管道。您正在对包含管道的字符串执行 eval
。这类似于执行 /bin/bash -c 'some |管道 |行'
。当前 shell 实际运行的是单个命令,因此它具有单个退出代码。
这里有两个选择:
- 摆脱
eval
(无论如何你都应该这样做,因为eval
通常是要避免的事情)并停止使用字符串作为命令(更多信息请参见 Bash FAQ 050关于为什么这样做是个坏主意。 - 将
echo "${PIPESTATUS[@]}"
移动到eval
中,然后捕获(并拆分/解析)结果输出。 (从几乎所有方面来看,这显然都是一个更糟糕的解决方案。)
关于linux - 内部变量 PIPESTATUS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30075050/