В настоящее время я работаю в сценарии оболочки, чтобы автоматизировать некоторые вещи (копирование файлов и сохранение их «даты изменения») . Я протестировал все команды в своей оболочке, но когда я запускаю их в сценарии, они работают некорректно.
Если я запустил это в своей оболочке, я получу соответствующий результат:
$> filename=/home/root/data/ABCD1234/20170123-231000.wav
$> echo "$filename"
/home/root/data/ABCD1234/20170123-231000.wav
$> cdate=$(date +%Y%m%d%H%M.%S -r $filename)
$> echo $cdate
201701232310.00
$> cp $filename $filename.bck
touch -t $cdate $filename.bck
Но когда я запустил следующий сценарий:
#!/bin/bash
# list desired files
files=$(find /home/root/data/ABCD1234/*)
# iterate over every file found
for filename in $files
do
echo "$filename"
cdate=$(date +%Y%m%d%H%M.%S -r $filename)
echo $cdate
cp $filename $filename.bck
touch -t $cdate $filename.bck
done
exit 0
Я получаю следующий результат (при условии, что в этой папке есть 2 файла)
/home/root/data/ABCD1234/20170123-231000.wav
': No such file or directory/data/ABCD1234/20170123-231000.wav
/home/root/data/ABCD1234/20170123-231500.wav
': No such file or directory/data/ABCD1234/20170123-231500.wav
PS : Я использую дистрибутив ARAGO, и большинство команд оболочки являются перенаправлением на BusyBox.
PS: В моем исходном скрипте я фактически не копирую файлы, поэтому сохранение отметки времени в команде cp не решит мою проблему.
Проблема заключается в цитировании переменной $ files
. Он присвоит все имена файлов сразу filename
.
Если вас интересуют только файлы *. Wav
в / home / root / data / ABCD1234 /
, вы можете сделать это вместо этого:
for filename in /home/root/data/ABCD1234/*.wav
do
echo "$filename"
cdate="$( date +%Y%m%d%H%M.%S -r "$filename" )"
echo "$cdate"
cp "$filename" "$filename.bck"
touch -t "$cdate" "$filename.bck"
done
Используя ] find
:
find /home/root/data/ABCD1234/ other options | while read -r filename; do # loop as before done
Проблема могла возникнуть только из-за "files", поскольку сценарий @Kusalananda отлично работает, когда для его заполнения используется "find".
Оказывается, в этой строке может быть CR-LF вместо LF (инструмент, который я использовал, был портом из программы Windows C ++).
Удаление CR в переменной решило проблему. Чтобы удалить, я использовал следующую строку перед циклом for
files=${files//[$'\t\r\n']}