На этот вопрос уже есть ответ здесь:
У меня проблема. Вот мой сценарий bash для объединения видео с подпрограммами:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW\ s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o $url0$i.mkv $url0$i.mkv $url0$i.srt
rm $url0$i.srt
else
mkvmerge -o $url1$i.mkv $url1$i.mkv $url1$i.srt
rm $url1$i.srt
fi
done
Файл имеет имена, например, «DW s11e05.mkv», и они действительно существуют в каталоге.
И вот результат:
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e09.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e09.srt': No such file or directory
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e10.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW\': No such file or directory
rm: cannot remove 's11e10.srt': No such file or directory
Как видите '\' перед пробелом здесь не работает. Я тоже пробовал использовать эхо, но ничего не изменилось (м.б. я неправильно использовал).
Простите за мой немного нуби-стиль.
Необходимо заключить переменные в кавычки. Это должно сделать то, что Вы хотите:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o "$url0$i.mkv" "$url0$i.mkv" "$url0$i.srt" &&
rm "$url0$i.srt"
else
mkvmerge -o "$url1$i.mkv" "$url1$i.mkv" "$url1$i.srt" &&
rm "$url1$i.srt"
fi
done
Обратите внимание, что я также добавил a &&
после каждого mkvmerge
управляйте так rm
только выполнения, если mkvmerge
было успешно. Вы не хотите удалять файл подзаголовка, если слияние перестало работать!
Тем не менее, хотя нет абсолютно ничего неправильно с Вашим подходом, я чувствую, что Вы могли сделать его значительной более простой и более изящной оболочкой использования globbing вместо этого:
#!/bin/bash
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
srtFile=${file//.mkv/.srt}
mkvmerge -o "$file" "$file" "$srtFile" && rm "$srtFile"
done
Вам даже не нужен сценарий для этого. Можно просто выполнить его непосредственно в терминале как один лайнер:
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
mkvmerge -o "$file" "$file" "${file//.mkv/.srt}" && rm "${file//.mkv/.srt}";
done
Переменные кавычки для предотвращения разделения слова. Между прочим, двойные кавычки на целой строке предпочтительный стиль.
#!/bin/bash
# Also exit if this fails
cd "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/" || exit
url0="DW s11e0"
url1="DW s11e"
for (( i=1; i<11; i++ )); do
# Also why use "not greater-than" when "less-than-or-equal" exists?
if [ $i -le 9 ]; then
# Also you can DRY* out this part with variables.
url="$url0"
else
url="$url1"
fi
# Also when concatenating variables, it's clearer to use the "${var}" style. **
f_mkv="${url}${i}.mkv"
f_srt="${url}${i}.srt"
mkvmerge -o "$f_mkv" "$f_mkv" "$f_srt"
rm "$f_srt"
done
Shellcheck действительно полезен для нахождения проблем как это в сценариях оболочки.
* DRY = не повторяют себя
** Или Вы могли использовать printf -v
, но это не большое улучшение в этом случае. Например,
printf -v f_mkv "%s%s.mkv" "$url" $i