2012-01-16 61 views
10

我对bash脚本非常陌生,对于我的第一个脚本尝试,我将文件提交给同一服务器中的教授dropbox。Bash脚本错误捕获

的代码是这样的:

#! /bin/bash 
echo "Submit Lab$1? \c" 

read choice 

if [ $choice = "y" ]; then 
    echo "Sending to Prof's dropbox..." 
    cp -r /path/to/lab$1 /path/to/dropbox 
else 
    echo "Submission terminated." 
fi 

该命令的用法是简单的“$ submit 1”(1为一个整数,对应于我想要提交该实验室)

的bash脚本追加输入参数(一个整数)到必要的文件名(目录),然后使用cp将该目录提交给我的教授的保管箱。

更多的是为了学习而不是绝对的必要性,我想创建一个干净的提示符,它会捕获任何cp错误(如文件不存在),并且能够输出我自己的错误消息。

所以基本上是这样的:

echo "Submit lab$1?" 

read choice 

echo "Send to Prof's dropbox" 
cp -rv /path/to/lab$1 /path/to/dropbox 

<catch any errors from cp> 

if [ cp has errors ] 

    echo "Submission failed." 

else if [ cp has no errors ] 

    echo "Submission successful." 

And so on... 

我明白,我可以用详细模式,这本身cp打印出错误,但正如前面所说,我这样做是为学习误差的目的在bash中捕捉并能够做出干净的提示。

任何帮助,将不胜感激。

谢谢!


另外:我有一个类似的脚本来提交我的笔记本电脑实验室,使用scp。假设我已经回答了这个问题,我是否可以将解决方案以完全相同的方式应用于scp?

编辑:我不希望cp错误输出到壳!最常见的错误可能是“不能stat blah:没有这样的文件或目录”。我想抓住那个错误,并简单地说“提交失败”。

编辑#2: jcollado的回答是正确的,问题是在我的部分。没有用适当的“fi”结束嵌套if-else

修复后,它按预期工作。仍然需要捕捉错误输出,但我相信我知道我需要自己去解决这个问题,因此就我而言,这个问题得到了解答。

FINAL EDIT:啊,什么 - 重定向是如此简单我想我会把解决方案放在这里。如果使用Linux,只需添加“2>/dev/null”(如果你不想错误信息被保存在任何文件做)的cp后,使“cp -r /first/path /second/path 2>/dev/null

回答

23

尽管你可以测试$?你也可以直接测试命令的退出状态:

if cp -rv /path/to/lab$1 /path/to/dropbox 
then echo Submission successful 
fi 
exit $? 

的错误已经上报标准按cp错误。如果cp成功,则显示的exit将以状态0(成功)退出;否则,以cp退出的状态退出。显然,如果你愿意,你可以将它包装在一个循环中,或者你可以使它成为非交互式(但任何退出都会终止脚本)。

+0

感谢您的替代解决方案。基于简单的最佳答案。 – skippr

+0

我相信上面的退出代码将始终为零。如果'cp'失败(返回非0),则'if'将返回0. bash的'echo'总是返回0.从手册页中,关于'if':*退出状态是最后执行的命令的退出状态如果没有条件测试真的,则为零。* –

+1

@ mr.spuratic:看起来你是对的。运行'如果为true;然后回显真实;网络连接; echo $?'在Bash,Korn shell中,Heirloom shell输出true然后是0;用“if false”代替它。然后回显真实;网络连接; echo $?',它只打印0.因此,'$?'状态不会保留'if'中执行的命令的退出状态。周围有许多方式,或多或少优雅。其中一个就是'status = 0;如果属实;然后回显真实;其他状态= 1;网络连接; echo $ status'。或者你可以做相反的事:'status = 1;如果属实;然后回显真实;状态= 0;网络连接; echo $ status'。 –

8

从以前的命令检查返回代码,你可以使用$?特殊的变量如下:

if [ "$?" -ne "0" ]; then 
    echo "Submission failed" 
    exit 1 
fi 

echo "Submission successful." 

此外,如果你想要一个干净的提示,你可以redired stderr作为解释here

最后,您还可以在使用scp的脚本中使用此功能,因为它的工作原理与您使用的命令无关。

+0

感谢您的提示(无双关语)回应!我会更多地关注stderr重定向,因为这似乎是“干净利索”解决方案所在。但是,您提供的代码不适用于失败的提交。它不打印“提交失败”。当cp失败时。但是,当cp失败时,忽略“提交成功”。 – skippr

+0

我注意到,当cp失败时,它执行后没有任何东西。 – skippr

+0

啊,问题在我身上。现在明白了。谢谢! – skippr

2
echo "Submit lab$1?" 

read choice 

echo "Send to Prof's dropbox" 
cp -rv /path/to/lab$1 /path/to/dropbox &>/dev/null 

[ $? -eq 0 ] && { #success, do something } || { #fail, do something } 

等等......