首页 > 解决方案 > 遍历子目录:如果一个命令失败,我该如何恢复?

问题描述

我有这个 for 循环

for repository in ./*/; do
    echo $repository && cd $repository && git checkout -b prod  && cd - >/dev/null;
done

但是如果分支 prod 已经存在,它会打印一条消息并退出循环。如何忽略此错误并转到下一个目录?

谢谢

标签: bashfor-loop

解决方案


所以问题是git checkout -b prod如果分支已经存在,则返回失败给shell。cd -由于它使用条件运算符连接到下一个命令 ( ),因此&&下一个命令仅在git成功时运行。因此,当git失败时,cd不会运行,并且您的 shell 会留在错误的目录中以继续其循环。

通常,如果您希望代码在命令失败的情况下继续运行,请使用;或 换行符而不是&&.

但是在这种情况下,更好的解决方案是只cd在子shell中执行,这样它就不会影响外部循环的工作目录,并且您根本不必这样做cd -

for repository in ./*/; do
   echo "$repository" && (
    cd "$repository" && git checkout -b prod
   )
done

即使分支创建失败,它也能正常工作。它仍然会打印出错误信息;如果您不想看到这些,请添加重定向:

 for repository in ./*/; do
   echo "$repository" && (
    cd "$repository" && git checkout -b prod
   ) 2>/dev/null
done

我还引用了$repository命令中的扩展,您几乎应该总是在 shell 脚本中这样做。例如,对于不带引号的版本,如果任何 repo 目录名称中包含空格,您将收到错误消息。

此外,“在子外壳中没有副作用”对于在不同的目录中完成部分工作非常有用,但它的应用范围更广。如果您有一个更复杂的循环来设置任何 shell 变量或在子目录中的任何内容,那么这些也会丢失。只是要记住的事情。


推荐阅读