我设法凑齐了以下脚本,将文件从一个Samba共享移动到另一个。它似乎适用于所有合法的Windows文件名,除非文件名中有美元字符($)。它失败的典型文件名是:〜$ file.doc
任何帮助都将不胜感激。
#!/bin/bash
# Script to move old files from public to quarantine
srcbase=/net/public
destbase=/net/quarantine
logfile=$srcbase/moved.log
date > $logfile 2>1&
find $srcbase -noleaf -atime +30 -print0 | while IFS="" read -r -d "" file ; do
if [ -f "$file" ]; then
relname="${file#*$srcbase}"
destname="$destbase$relname"
destdir="$(dirname "$destname")"
if [ ! -d "$destdir" ]; then
cmd1="mkdir -p \""$destdir"\""
eval "$cmd1" >> $logfile 2>&1
fi
cmd="mv --backup=t -v \""$file"\" \""$destname"\""
eval "$cmd" >> $logfile 2>&1
if [ -e "$destname" ]; then
cmd2="touch -a \""$destname"\""
eval "$cmd2" >> $logfile 2>&1
fi
fi
done
date >> $logfile 2>1&
echo Deleting empty directories from "$srcbase" >> $logfile 2>&1
find "$srcbase" -type d -empty -delete >> $logfile 2>&1
答案 0 :(得分:3)
你当然是。您正在使用eval
。
BASH FAQ entry #50
答案 1 :(得分:3)
问题可能来自于在一个被证实的变量中使用文件名。
如果你在eval的设置中使用单引号,它可以防止在那里解释$。:
cmd2="touch -a '$destname'"
创建cmd时仍会替换$destname
。
但是我强烈建议您不要在文件系统上找到的文件名中构建eval。这是一个巨大的后门。例如:如果某个恶作剧者在源文件系统上创建文件名; rm -rf /
该怎么办?
答案 2 :(得分:3)
您的问题是您使用eval
。我建议反对它,因为它非常非常非常必要且非常难以使用。在你的情况下,我认为不需要它
如果用此
替换循环内容 if [ -f "$file" ]; then
relname="${file#*$srcbase}"
destname="$destbase$relname"
destdir="$(dirname "$destname")"
if [ ! -d "$destdir" ]; then
mkdir -p "$destdir" >> $logfile 2>&1
fi
mv --backup=t -v "$file" "$destname"
if [ -e "$destname" ]; then
touch -a "$destname" >> $logfile 2>&1
fi
fi
即使文件名中包含$,它也应该可以正常工作。
您是否发现情况并非如此?