我目前正在使用 shell 脚本来自动执行一些操作(复制文件并保留其“更改日期”)。我在 shell 上测试了所有命令,但是当我在脚本上运行它们时,它们的行为不正确。
如果我在 shell 上运行它,我会得到适当的结果:
$> 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 发行版,大多数 shell 命令都是重定向到 BusyBox。
PS:在我的原始脚本中,我实际上并没有复制文件,因此在 cp 命令上保留时间戳并不能解决我的问题。
答案1
问题在于$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
:
找到/home/root/data/ABCD1234/ 其他选择 | while read -r 文件名;做 #像以前一样循环 完毕
答案2
该问题只能来自“files”变量,因为当使用“find”填充它时,@Kusalananda 的脚本可以完美运行。
事实证明,这个字符串可以有 CR-LF 而不是 LF(我使用的工具是来自 Windows C++ 程序的端口)。
删除变量中的 CR 解决了问题。要删除,我在 for 循环之前使用了以下行
files=${files//[$'\t\r\n']}