具有多个命令的条件

具有多个命令的条件

可以做这样的事吗?

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。这不是实际信号,但ERRbash 中的 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

相关内容