迭代 pushd-popd 目录列表时是否需要 if-fi 段?

use*_*970 -1 shell-script control-flow pushd syntax

我使用以下代码,这是我用来更新我的 WordPress 网站的脚本的一部分:

#!/bin/bash
drt="/var/www/html"
for dir in ${drt}/*/; do
    if pushd "$dir"; then
        wp plugin update --all --allow-root
        wp core update --allow-root
        wp language core update --allow-root
        wp theme update --all --allow-root
    popd
    fi
done
Run Code Online (Sandbox Code Playgroud)

我学到的具体的pushd-popd当我搜索一种方式来更新我的所有WordPress的情况下一气呵成在此代码中使用的模式。

我不清楚为什么这段代码包含一个if-fi段。

我的问题

我可以以某种方式更改语法,以便我拥有基本相同的模式但没有if-fi段吗?

例如,而不是这样:

if pushd "$dir";
popd
    commands
fi
Run Code Online (Sandbox Code Playgroud)

我会有这样的伪代码:

pushd "$dir";
    commands
popd
Run Code Online (Sandbox Code Playgroud)

为什么我问这个

我可以想象我们如何在没有if-fi语句(伪代码)的情况下告诉计算机这样的事情:

for dir in ${drt}/*; do pushd "$drt"; then
    commands
popd
Run Code Online (Sandbox Code Playgroud)

笔记

  1. 您可能希望在答案中包含不同的方法(即根本没有pushd- popd)。

  2. 一个相关的问题

l0b*_*0b0 6

除了@Olorin 所写的内容之外,我认为这里可能存在一些误解。首先,for y in ${x}/*; do pushd "$y"; then结果

bash:意外标记“then”附近的语法错误


其次,缩进可能会误导您关于实际发生的事情。使用原始代码的正确格式版本:

for y in ${x}/*/
do
    if pushd "$y"
    then
        command1
        command2
        popd
    fi
done
Run Code Online (Sandbox Code Playgroud)

换句话说,所有 command1,command2popd仅在初始pushd成功时运行。如果你改为写

for y in ${x}/*/
do
    pushd "$y"
    command1
    command2
    popd
done
Run Code Online (Sandbox Code Playgroud)

并且没有errexit守卫到位,失败pushdpopd不会影响脚本的其余部分。这可能会导致在错误的目录中运行command1command2然后可能会弹回与此代码无关的另一个目录这可能会带来灾难性的后果。


最后,我认为pushd+ 命令 +popd是一种反模式,因为它为复杂的上下文已经是一个大问题的语言增加了更多的上下文(因此增加了认知开销和风险)。解决此问题的最常见方法是将路径(理想情况下是绝对路径)传递给命令,如下所示:

for y in "$x"/*/
do
    command1 "$y"
    command2 "$y"
done
Run Code Online (Sandbox Code Playgroud)