Bash脚本错误捕获

ski*_*ppr 13 error-handling bash

我是bash脚本的新手,对于我的第一次脚本尝试,我将文件提交到同一服务器中我教授的Dropbox.

代码是这样的:

#! /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
Run Code Online (Sandbox Code Playgroud)

该命令的用法只是" $ submit 1"(1是一个整数,对应于我要提交的实验室)

bash脚本将输入的参数(单个整数)附加到必要的文件名(目录),然后使用将该目录提交到我的prof的dropbox 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...
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用详细模式,并且它cp本身会输出错误,但如前所述,我这样做是为了学习错误捕获bash并能够提供干净的提示.

任何帮助,将不胜感激.

谢谢!


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

编辑:我不希望cp错误输出到shell!最常见的错误可能是"不能统计错误:没有这样的文件或目录".我想抓住这个错误,简单地说"提交失败".

编辑#2: jcollado的答案是正确的,问题在于我.没有if-else以适当的" fi." 结束嵌套.

在修好之后,它按预期工作.仍然需要捕获错误输出,但我相信我知道我需要在哪里自己解决这个问题,所以就我而言,这个问题得到了回答.

最终编辑:啊,到底是什么 - 重定向是如此简单我想我会把解决方案放在这里.如果使用Linux,只需添加" 2>/dev/null"(如果你不想错误信息被保存在任何文件中那样)后,cp使" cp -r /first/path /second/path 2>/dev/null"

Jon*_*ler 25

虽然您可以测试$?,但您也可以直接测试命令的退出状态:

if cp -rv /path/to/lab$1 /path/to/dropbox
then echo Submission successful
fi
exit $?
Run Code Online (Sandbox Code Playgroud)

错误已经报告为标准错误cp.该exit显示将与状态0(成功),如果退出cp是成功的; 否则,它以退出的状态cp退出.

显然,如果需要,可以将其包装在循环中,或者可以使其成为非交互式(但任何出口都会终止脚本).

  • @mr.spuratic:看起来你是对的。运行`if true; 然后回显 true;菲;在 Bash、Korn shell、Heirloom shell 中 echo $?` 打印 true,然后打印 0;将其替换为“如果为假;然后回显 true;菲;echo $?` 并且只打印 0。因此,`$?` 状态不会保留在 `if` 中执行的命令的退出状态。有一些方法可以解决这个问题,或多或少优雅。其中之一是 `status=0; 如果属实; 然后回显 true;否则状态=1;菲;回显$状态`。或者你可以做相反的事情:`status=1; 如果属实; 然后回显 true;状态=0;菲;回显$状态`。 (2认同)

jco*_*ado 11

要检查上一个命令的返回代码,可以使用$?特殊变量,如下所示:

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

echo "Submission successful."
Run Code Online (Sandbox Code Playgroud)

此外,如果您想要一个干净的提示,您可以stderr按照此处的说明进行重新设置.

最后,您还可以在使用的脚本中使用scp它,因为无论您使用的命令如何,它都可以使用.

  • `exit`的参数是你自己脚本的结果代码.最好确保退出代码在成功时为0,否则为非零,这样更高级别的脚本可以调用您的脚本并使用其结果代码来处理任何错误. (2认同)