Я искал уже несколько часов, но не могу найти ответа на этот вопрос. Я пытаюсь создать сценарий оболочки в тюрьме FreeNAS 11 (freebsd), который переместит некоторые файлы во вложенную папку. У меня он правильно получает пути, но когда приходит время переместить файлы, он не работает (когда имя файла содержит пробелы).
#!/bin/sh
# Primary dir to scan
SRC_DIR=/mnt/transcode/batch/
WORKING_DIR = "${SRC_DIR}working/"
for FILE in $SRC_DIR*
do
# only run against files...
if test -f "${FILE}"
then
#FILE_NAME=$(basename "$FILE" | sed 's/ /\\ /g') # replace spaces with escaped space
#mv "$SRC_DIR""$FILE_NAME" "$WORKING_DIR""$FILE_NAME"
#mv $SRC_DIR$FILE_NAME $WORKING_DIR$FILE_NAME
FILE_NAME=$(basename "$FILE")
mv \""$SRC_DIR""$FILE_NAME"\" \""$WORKING_DIR""$FILE_NAME"\" #wrap each parameter in double quotes
# copying this output back into terminal works
#echo mv \""$SRC_DIR""$FILE_NAME"\" \""$WORKING_DIR""$FILE_NAME"\"
fi
done
Приведенный выше код также содержит несколько дополнительных вещей, которые я тоже пробовал.
При запуске скрипта я получаю следующее сообщение
mv: rename "/mnt/transcode/batch/REDACTED FILE NAME.mkv" to "/mnt/transcode/batch/working/REDACTED FILE NAME.mkv": No such file or directory
Интересно то, что когда я беру вывод echo mv \""$SRC_DIR""$FILE_NAME"\" \""$WORKING_DIR""$FILE_NAME"\" и вставляю его обратно в терминал, он работает отлично.
Я запускаю это через SSH как root. Разрешения целевой папки: drwxrwxr-x+
Я запускаю свой скрипт через ./test.sh (как пользователь root)
Есть ли другой способ сделать это или есть проблема с моим сценарием?
Любая помощь приветствуется.
PS В моей тюрьме нет / bin / bash, не уверен, что это имеет значение.
--Редактировать--
Вот (надеюсь) окончательный код, который я хочу выполнить:
#!/bin/sh
# Primary dir to scan
SRC_DIR=/mnt/transcode/batch/
DEST_DIR = "${SRC_DIR}converted/"
WORKING_DIR = "${SRC_DIR}working/"
DONE_DIR = "${SRC_DIR}orginal/"
# only get files, not directories
#for FILE in `ls -p $SRC_DIR | grep -v /`
for FILE in $SRC_DIR*
do
# only run against files...
if test -f "${FILE}"
then
FILE_NAME=$(basename "$FILE" | sed 's/ /\\ /g')
# move the file to the working dir
mv $SRC_DIR$FILE_NAME $WORKING_DIR$FILE_NAME
# vars for later
MEDIA_FILE=$WORKING_DIR$FILE_NAME
# Get some into about the current file
AUDIO_CODEC = "$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=s=x:p=0 $MEDIA_FILE)"
MEDIA_INFO = "$(ffprobe -v error -select_streams v:0 -show_entries stream=height,width -of csv=s=x:p=0 $MEDIA_FILE)"
VIDEO_HEIGHT = "$(echo "$MEDIA_INFO" | cut -d 'x' -f2)"
VIDEO_WIDTH = "$(echo "$MEDIA_INFO" | cut -d 'x' -f1)"
# start up handbrake
HandBrakeCLI -i $WORKING_DIR$FILE_NAME -o $DEST_DIR${FILE_NAME%.*}.mkv -f av_mkv -m -e x264 -q 22 --vfr --audio-lang-list eng -E copy:$AUDIO_CODEC --crop 0:0:0:0 -w $VIDEO_WIDTH -l $VIDEO_HEIGHT --subtitle-lang-list eng
# move the file to the done dir
mv $WORKING_DIR$FILE_NAME $DONE_DIR$FILE_NAME
fi
done
Конечная цель - переместить отдельный файл в рабочий каталог, пока он транскодируется, а затем переместить его в готовую папку.





Проблема в том, что вы добавляете лишние кавычки к именам файлов.
mv \"foo\" bar
пытается переименовать файл с буквальным названием "foo" (включая кавычки).
Также не используйте ALL_UPPERCASE для своих переменных. ALL_UPPERCASE используется системой (например, HOME) или самой оболочкой (например, RANDOM, PWD).
Я бы сделал так:
src_dir=/mnt/transcode/batch
working_dir = "$src_dir/working"
for file in "$src_dir"/*; do
# only run against files...
if test -f "$file"; then
mv -- "$file" "$working_dir/"
fi
done
Вы можете mv прямо в каталог, не нужно сначала извлекать базовое имя.
Не проверено, но вот остальная часть вашего скрипта. Я добавил недостающие кавычки, удалил странные дополнения с обратной косой чертой и т. д.
#!/bin/sh
# Primary dir to scan
src_dir=/mnt/transcode/batch
dest_dir = "$src_dir/converted"
working_dir = "$src_dir/working"
done_dir = "$src_dir/orginal"
for src_file in "$src_dir"/*; do
if test -f "${src_file}"; then
basename = "${src_file##*/}"
working_file = "$working_dir/$basename"
# move the file to the working dir
mv -- "$src_file" "$working_file"
# Get some into about the current file
audio_codec = "$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=s=x:p=0 "$working_file")"
media_info = "$(ffprobe -v error -select_streams v:0 -show_entries stream=height,width -of csv=s=x:p=0 "$working_file")"
video_height = "${media_info#*x}"
video_width = "${media_info%%x*}"
# start up handbrake
HandBrakeCLI -i "$working_file" -o "$dest_dir/${basename%.*}.mkv" -f av_mkv -m -e x264 -q 22 --vfr --audio-lang-list eng -E copy:"$audio_codec" --crop 0:0:0:0 -w "$video_width" -l "$video_height" --subtitle-lang-list eng
# move the file to the done dir
mv -- "$working_file" "$done_dir/"
fi
done
Да! Большое спасибо @melpomene - теперь мне просто нужно изучить его и выяснить, где я ошибся
Ах, не видел этого, пока не опубликовал дополнительные подробности. Я только что протестировал его, и он работает как отдельный скрипт. Я посмотрю, смогу ли я включить это в свой более крупный сценарий.