我正在处理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
怎么会影响到那个?如果我注释掉那一行,它会按预期工作。
答案 0 :(得分:2)
如果您希望i
是本地的,则需要将其声明为:
shift_contents() {
local i
# ...etc...
}
move_exercise() {
local i
# ...etc...
}
否则,两个函数之间只共享一个名为i
的变量。当该变量包含文件名时,其数值为0(除非该文件名也是分配了非零数值的shell变量的名称) - 所以当您在分配文件名后递减它时,它将变为负数。