我有以下函数中的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语句(吗?
您可以设置一个变量并在第一次迭代中更改它:
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和环境变量发生冲突- 引用所有扩展名以防止单词拆分和globbing(
[[...]]
中的左侧自动引用( - 我用的是
$folder
而不是${folder}
,但这只是个人品味
如果您需要保留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
您还可以解释整个任务以获得更准确的解决方案。
我知道你说过你想保持代码的形状,但从风格上讲,我总是犹豫是否在循环中使用if
来构建代码,只是为了处理数组的第一个元素——我更喜欢把代码吊出来,以强调第一个元素受到了特殊处理。另一种选择是添加一个状态变量,这永远不会让代码变得更清晰。
在你的情况下,怎么样
if [ ${#FOLDER[@]} -ne 0 ]; then
local files=$(stamp-files ${FOLDER[0]})
rsync -rvh --delete-after ${files} ${folder_dest}
for folder in ${FOLDER[@]:1}; do
rsync -rvh --delete-after ${folder} ${folder_dest}
done
fi