我正在编写一个 bash 脚本,它基本上会移动目录的全部内容,其中文件名都以数字(0001、0002 等)开头。我以相反的顺序遍历这些文件,以先将最后一个向下移动。
我有一个函数可以遍历文件并调用另一个函数来实际移动它们。当我调用第二个函数时,它使 for 循环短路并退出。我不明白为什么。
validation_dir="scripts/validation"
content_directories=($validation_dir "tutorials")
function shift_contents() {
local start_index=$1
local positions=$2
local files=(${validation_dir}/*)
for ((i=${#files[@]}-1; i>=0; i--)); do
# Only gets called once
echo $i
local f="${files[$i]}"
local old_index=$(echo $f | tr -dc '0-9' | sed -e 's/^0*//')
if [ "$old_index" -lt "$start_index" ]
then
# Only start when we're at the start index
continue
fi
local new_index=$((old_index + positions))
# When this is called, it exits the loop
move_exercise $old_index $new_index
done
}
下面是进行移位的函数:
function move_exercise() {
local start_index=$1
local end_index=$2
local start_prefix=$(echo_filename_prefix $start_index)
local end_prefix=$(echo_filename_prefix $end_index)
for i in ${content_directories[@]}; do
start_file_glob="${i}/${start_prefix}*"
for f in $start_file_glob; do
if [ -e $f ]
then
start_filename=$f
else
log_error "No content found with index ${start_index}"
exit 1
fi
break
done
end_file_glob="${i}/${end_prefix}*"
if [ -e $end_file_glob ]
then
log_error "Content was already found for end index ${end_index}: ${end_file_glob}"
exit 1
fi
# Generate the new file name
new_filename="${start_filename/$start_prefix/$end_prefix}"
# We get down here once
echo $start_filename $new_filename
done
return
}
看起来第二个函数导致第一个函数提前退出,但我不明白这是怎么发生的。看看发生了什么?
编辑:
当我使用 bash -x script.sh
运行时,当它应该再进行一次迭代时,它以以下输出结束:
+ echo path/to/second-to-last-file new-path
+ return
+ (( i-- ))
+ (( i>=0 ))
这是否意味着它没有通过 for 循环条件检查?如果是这样,move_exercise
会如何影响它?如果我注释掉该行,它会按预期工作。
最佳答案
如果你想让 i
是本地的,你需要这样声明它:
shift_contents() {
local i
# ...etc...
}
move_exercise() {
local i
# ...etc...
}
否则只有一个名为i
的变量在两个函数之间共享。当该变量包含文件名时,其数值为 0(除非该文件名也是分配了非零数值的 shell 变量的名称)——因此当您在分配文件名后递减它时,它变为负数。
关于linux - BASH for循环在调用函数后退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43194914/