在Bash中的for循环中仅运行一次命令

时间:2018-10-26 13:34:46

标签: bash for-loop iteration

我从函数中得到以下bash代码模式:

for folder in ${FOLDER[@]}; do
    if [ $# -ne 0 ]; then
        rsync -rvh --delete-after ${folder} ${folder_dest}
    else
        local zipFile=$(stamp-files file.zip)
        unzip -q ${zipFile} "${folder}"*  -d "${folder_src}"
        rsync -rvh --delete-after ${folder_src}${folder} ${folder_dest}
        rsync -rvh --delete-after ${folder_src}${folder} ${folder_dest2}
    fi
done

因此在此函数中,我在for循环中有一个if语句。正如您在其他部分中看到的那样,存在对另一个函数stamp-files的调用。仅在第一次迭代中才需要对其他函数进行此调用,即使它不会引起任何问题,也可以通过只调用一次来改善它。

您知道如何简单地保持代码的形状(for循环中的if语句)吗?

3 个答案:

答案 0 :(得分:1)

您可以设置变量并在第一次迭代中对其进行更改:

first='yes'
for folder in "{folders[@]}"; do
    if [[ $first == 'yes' ]]; then
        local files=$(stamp-files "$folder")
        rsync -rvh --delete-after "$files" "$folder_dest"
        first='no'
    else
        rsync -rvh --delete-after "$folder" "$folder_dest"
    fi
done

您尝试使用$#的方法无效:这是位置参数的数量,与迭代次数或类似次数无关。

我还更改了一些内容:

  • folders而非FOLDER;大写变量名更可能与shell和环境变量发生冲突
  • 引用所有扩展名以防止单词分裂和加乱([[...]]的左侧被自动引用)
  • 我使用$folder而不是${folder},但这实际上只是个人喜好

答案 1 :(得分:0)

如果您需要保留for循环和if内部结构:

unset stamp_files_done
for folder in ${FOLDER[@]}; do
    if [ $# -ne 0 ]; then
        rsync -rvh --delete-after ${folder} ${folder_dest}
    else
        if [[ -z ${stamp_files_done+x} ]]; then local files=$(stamp-files ${folder}); stamp_files_done=""; fi
        rsync -rvh --delete-after ${files} ${folder_dest}
    fi
done

您还可以说明总体任务,以获得更准确的解决方案。

答案 2 :(得分:0)

我知道您已经说过要保持代码的形状,但是从风格上讲,我总是不愿意在循环内使用A matching symbol file was not found in this folder来构造代码,只是为了处理数组的第一个元素-我更喜欢将代码提升出来,以强调第一个元素已被特别对待。另一种选择是添加一个状态变量,该变量永远不会使代码更清晰。

您的情况如何

if