我有以下代码..
while read copy
do
cp -v $copy | tee -a $LOGFILE
echo $?
if [[ $? -ne 0 ]]
then
echo "Error copying files. Exiting ..." | tee -a $LOGFILE
exit 1
fi
done < copy_new_files.tmp
..如果文件无法复制以解决诸如拒绝权限之类的错误,我希望脚本停止。
脚本的输出没有在权限被拒绝错误上生成错误代码..
+ read copy
+ cp -v acts035.fmt /home/test/gp/efin/source/pl/acts035.fmt
cp: cannot create regular file `/home/test/gp/efin/source/pl/acts035.fmt': Permission denied
+ tee -a /home/test/gp/efin/fixes/12345/efin_fix_copy_12345.log
`acts035.fmt' -> `/home/test/gp/efin/source/pl/acts035.fmt'
+ echo 0
0
如果出现错误,如何让脚本暂停?
非常感谢。
答案 0 :(得分:3)
一些小阴险的东西,我希望不要过度:
第一个问题是$?
返回最后一个退出错误代码。
因此,当您在以下行中执行echo $?
时,在这种情况下将$?
设置为新值0
:我看不出echo
命令必须具有的原因失败。
第二个更隐蔽的问题是先前命令是管道。因此,要使用的变量是${PIPESTATUS[0]}
而不是$?
。 (有[0]
,因为它是一个数组,我们希望存储在第一个组件中的值是第一个命令的退出状态。
您可以再次将此值存储在变量中,也可以在测试后立即执行。否则,使用其他命令将再次重置变量值。
要暂停执行脚本,应该写一个像read -p x < /dev/tty
这样的输入行。这次是阴险的是我们克服了来自tty
的输入标准输入刷新。
使用read -r
比read
更安全。
-r raw input - 禁用读取数据中反斜杠转义和行继续的解释
所以代码变体应该是:
while read -r copy
do
cp -v $copy | tee -a $LOGFILE
# echo $? ${PIPESTATUS[0]} # NOT HERE else you loose it
if [[ ${PIPESTATUS[0]} -ne 0 ]] # $? was referred to the last command.
then # Use ${PIPESTATUS[0]} instead
echo "Error copying files. ${copy} Exiting ..." | tee -a $LOGFILE
# It will wait that you press return
read -p "Press CTRL-C to interrupt, RETURN to continue " x < /dev/tty
# exit 1 # It will not exit: (#) means comment.
fi
done < copy_new_files.tmp
注意:正如chepner 所建议的那样捕获cp
的退出状态的问题也可以通过将while循环的标准输出管道传输到tee
的单个调用来解决。比单独的cp
和echo
,更优雅。当然在这种情况下,您将在输出文件中写入循环中打印的所有文本,甚至不需要“按CTRL-C中断,RETURN继续”我添加的行。