可以做这样的事吗?
if
rsync $folder/coopshop/prod $folder2/coopshop
rsync $folder/coopweb/prod $folder2/coopweb
rsync $folder/unihobbyshop/shop $folder2/unihobbyshop
rsync $folder/unnihobbyweb/web $folder2/unihobbyweb
then
echo "OK! rsync done!"
else
echo "Error! rsync crashed!"
fi
我知道有可能在行尾使用\
字符,但这不是一个优雅的解决方案。有没有更好的方法?
答案1
考虑set -e
。
如果这是在脚本中,那么您可能希望完全删除if
...then
并将其放在set -e
脚本顶部。这样,如果任何命令失败,脚本就会立即停止。当任何这些rsync
命令失败时,它们将显示解释失败的错误消息,因此您可能根本不需要编写自己的消息。
如果要在运行命令之前显示已运行的命令,请使用set -x
。您可以通过编写 来将两者结合起来set -ex
。
有了&&
,您就不需要 了\
。
如果你决定按照你所展示的内容写点东西,那么正如 Ronny Blomme 所说你可以用 分隔命令&&
。请注意,你不需要在子壳层,即你不需要将它们封闭起来括号。
如果你&&
在行尾写了一个操作符,那么你不需要写\
来指定行的延续。命令不能以&&
(逻辑和)或||
(逻辑或者),这样 shell 就会继续解析下一行。
if
rsync "$folder/coopshop/prod" "$folder2/coopshop" &&
rsync "$folder/coopweb/prod" "$folder2/coopweb" &&
rsync "$folder/unihobbyshop/shop" "$folder2/unihobbyshop" &&
rsync "$folder/unnihobbyweb/web" "$folder2/unihobbyweb"
then
echo 'OK! rsync commands completed successfully!'
else
echo 'Error! some rsync command failed!'
fi
您不必将其放在&&
行尾。&&
如果您愿意,可以在同一行中编写多个命令,并用 分隔。
请注意,正在测试的最后一个命令并不以&&
because结尾&&
分开命令。如果任何命令失败,其他命令将不会运行。
运行所有命令,即使其中一些命令失败
您可能希望运行所有rsync
命令,即使其中一些命令失败,然后测试是否任何其中的命令失败并相应运行。为此,您可以捕获ERR
。这不是实际信号,但ERR
bash 中的 signal_spec 会捕获因任何原因失败的命令,包括崩溃(包括 SIGINT)。请参阅pLumo 的回答(但省略set -e
继续)和William Pursell 的这篇文章;有关更多常规信息,请参见 的输出help trap
。
我喜欢这样做(插入像你这样的命令)是:
failed=
trap 'failed=yes' ERR
rsync "$folder/coopshop/prod" "$folder2/coopshop"
rsync "$folder/coopweb/prod" "$folder2/coopweb"
rsync "$folder/unihobbyshop/shop" "$folder2/unihobbyshop"
rsync "$folder/unnihobbyweb/web" "$folder2/unihobbyweb"
if [ -z "$failed" ]; then
echo 'OK! rsync commands completed successfully!'
else
echo 'Error! some rsync command failed!'
fi
关于我所做的其他更改...以及真正的测试。if command
rsync
你要使用的论点参数扩展所以我擅自双引号他们。否则,单词拆分和通配符将被执行。从上下文来看,您似乎不想要这些额外的扩展。(通常你不会这么做。)
请注意,与脚本打印的消息相反,您实际上并没有测试是否有任何rsync
命令坠毁. 你正在测试是否有任何rsync
命令失败的。崩溃是程序异常终止,即进程被信号终止,通常是由于错误或无法合理处理的情况。这比正常程序终止少见得多,正常程序终止本身可能会以退出状态出现,表明成功(零)或失败(其他数字)。如果rsync
做崩溃,上面的代码将要也能捕获这种情况。但实际上,它捕获的大多数情况都是程序正常终止,退出状态表示失败。
答案2
对于像你这样的脚本,我不会使用if
/ else
,而是启用出错时退出(set -e
)和陷印。
像这样:
#!/bin/bash
set -euo pipefail
trap 'echo "Error! rsync crashed!"' ERR INT
rsync $folder/coopshop/prod $folder2/coopshop
rsync $folder/coopweb/prod $folder2/coopweb
rsync $folder/unihobbyshop/shop $folder2/unihobbyshop
rsync $folder/unnihobbyweb/web $folder2/unihobbyweb
echo "OK! rsync done!"
答案3
尝试这个语法:
#!/bin/bash
mkdir dir1 dir2
echo "test1" > dir1/file1
echo "test2" > dir1/file2
if (rsync dir1/file1 dir2) && (rsync dir1/file2 dir2)
then
echo "OK! rsync done!"
else
echo "Error! rsync crashed!"
fi