我有一个 bash 脚本,其中有一个 while 循环用于读取文件内容,还有一个 for 循环用于迭代每一行(while 循环读取)。
但是,while 循环只执行一次,当我注释掉内部的 for 循环时,它会一直执行到最后。
内部 done 有可能结束外部 while 循环吗?如果是的话,我该如何防止这种情况发生?
我也在 for 循环期间更改了我的 IFS 变量,但我使用“SAVEIFS”变量将其改回原始变量。
while read -r line ; do
echo $line
IFS=' '
if [[ $line == *'.00'* ]]; then
if [[ $line == *'+'* ]]; then
# MANY FROM ONE
read -r -a SplitValues <<< $line
DIFFSCOUNT= echo $line | grep -o "+" | wc -l
IFS='+'
# to split multiple
URL=${SplitValues[0]}
youtube-dl -x --audio-format mp3 ${SplitValues[0]}
echo $DIFFSCOUNT
for i in "${ALLDIFFS[@]}"
do
IFS=' '
read -r -a ITLINE<<< $i
IFS='>'
read -r -a TITLE<<< $i
CLEANNAME=${TITLE[1]::-1}
ffmpeg -r 25 -i *.mp3 -ss ${iteratieLijn[0]} -to ${ITLINE[1]} -c copy -vb 20M $CLEANNAME.mp3
cp $CLEANNAME.mp3 AllTogether/
rm $CLEANNAME.mp3
done
rm *.mp3
else
# SPECIFIC ONE
read -ra SplitValues <<< $line
youtube-dl -x --audio-format mp3 ${SplitValues[0]}
IFS='>' # > change delimiter for saving the name
read -ra splitted<<< $line
CLEANNAme=${NaamGesplit[1]::-1}
fi
else
echo "---Just One, plain--"
fi
fi
done < "${file}"
答案1
首先,我修复了代码的缩进。这很重要,因为它可以帮助您在编写代码时发现错误。
代码通过后ShellCheck – shell脚本分析工具修复错误后我们得到以下结果:
#!/bin/bash
while read -r line
do
echo $line
IFS=' '
if [[ $line == *'.00'* ]]; then
if [[ $line == *'+'* ]]; then
# MANY FROM ONE
read -r -a SplitValues <<< $line
DIFFSCOUNT= echo $line | grep -o "+" | wc -l
IFS='+'
# to split multiple
URL=${SplitValues[0]}
youtube-dl -x --audio-format mp3 ${SplitValues[0]}
echo $DIFFSCOUNT
for i in "${ALLDIFFS[@]}"
do
IFS=' '
read -r -a ITLINE<<< $i
IFS='>'
read -r -a TITLE<<< $i
CLEANNAME=${TITLE[1]::-1}
ffmpeg -r 25 -i *.mp3 -ss ${iteratieLijn[0]} -to ${ITLINE[1]} -c copy -vb 20M $CLEANNAME.mp3
cp $CLEANNAME.mp3 AllTogether/
rm $CLEANNAME.mp3
done
rm *.mp3
else
# SPECIFIC ONE
read -ra SplitValues <<< $line
youtube-dl -x --audio-format mp3 ${SplitValues[0]}
IFS='>' # > change delimiter for saving the name
read -ra splitted<<< $line
CLEANNAme=${NaamGesplit[1]::-1}
fi
else
echo "---Just One, plain--"
fi
done < "${file}"
现在没有错误,但仍有许多警告需要解决:
$ shellcheck myscript
Line 2:
while read -r line
^-- SC2095: ffmpeg may swallow stdin, preventing this loop from working properly.
Line 4:
echo $line
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
echo "$line"
Line 9:
read -r -a SplitValues <<< $line
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
read -r -a SplitValues <<< "$line"
Line 10:
DIFFSCOUNT= echo $line | grep -o "+" | wc -l
^-- SC1007: Remove space after = if trying to assign a value (for empty string, use var='' ... ).
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
DIFFSCOUNT= echo "$line" | grep -o "+" | wc -l
Line 13:
URL=${SplitValues[0]}
^-- SC2034: URL appears unused. Verify use (or export if used externally).
Line 14:
youtube-dl -x --audio-format mp3 ${SplitValues[0]}
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
youtube-dl -x --audio-format mp3 "${SplitValues[0]}"
Line 15:
echo $DIFFSCOUNT
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
echo "$DIFFSCOUNT"
Line 19:
read -r -a ITLINE<<< $i
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
read -r -a ITLINE<<< "$i"
Line 21:
read -r -a TITLE<<< $i
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
read -r -a TITLE<<< "$i"
Line 23:
ffmpeg -r 25 -i *.mp3 -ss ${iteratieLijn[0]} -to ${ITLINE[1]} -c copy -vb 20M $CLEANNAME.mp3
^-- SC2095: Use ffmpeg -nostdin to prevent ffmpeg from swallowing stdin.
^-- SC2035: Use ./*glob* or -- *glob* so names with dashes won't become options.
^-- SC2154: iteratieLijn is referenced but not assigned.
^-- SC2086: Double quote to prevent globbing and word splitting.
^-- SC2086: Double quote to prevent globbing and word splitting.
>> ^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086, apply all SC2095)
ffmpeg -nostdin -r 25 -i *.mp3 -ss "${iteratieLijn[0]}" -to "${ITLINE[1]}" -c copy -vb 20M "$CLEANNAME".mp3
Line 24:
cp $CLEANNAME.mp3 AllTogether/
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
cp "$CLEANNAME".mp3 AllTogether/
Line 25:
rm $CLEANNAME.mp3
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
rm "$CLEANNAME".mp3
Line 27:
rm *.mp3
^-- SC2035: Use ./*glob* or -- *glob* so names with dashes won't become options.
Line 30:
read -ra SplitValues <<< $line
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
read -ra SplitValues <<< "$line"
Line 31:
youtube-dl -x --audio-format mp3 ${SplitValues[0]}
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
youtube-dl -x --audio-format mp3 "${SplitValues[0]}"
Line 33:
read -ra splitted<<< $line
^-- SC2034: splitted appears unused. Verify use (or export if used externally).
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
read -ra splitted<<< "$line"
Line 34:
CLEANNAme=${NaamGesplit[1]::-1}
^-- SC2034: CLEANNAme appears unused. Verify use (or export if used externally).
^-- SC2154: NaamGesplit is referenced but not assigned.
Line 39:
done < "${file}"
^-- SC2154: file is referenced but not assigned (for output from commands, use "$(file ...)" ).
$