是否有用于创建硬链接备份的实用程序?

时间:2014-09-27 15:20:59

标签: linux bash unix backup hardlink

我需要创建一个目录树的克隆,以便我可以清理重复的文件。

我不需要文件的副本,我只需要文件,所以我想创建一个带有硬链接的匹配树。

当我意识到我的备份需要数小时时,我在几分钟内把它扔在一起

它只是回显我在运行之前重定向到文件中检查的命令。

当然,通常的问题,比如包含引号或逗号的文件和目录都没有得到解决(bash脚本很糟糕,没有它,这个和包含前导破折号的文件)

是否有一些实用工具已经以稳健的方式实现了这一目标?

BASEDIR=$1
DESTDIR=$2
for DIR in `find "$BASEDIR" -type d` 
do
   RELPATH=`echo $DIR | sed "s,$BASEDIR,,"`
   DESTPATH=${DESTDIR}/$RELPATH
   echo mkdir -p \"$DESTPATH\"
done

for FILE in `find "$BASEDIR" -type f` 
do
   RELPATH=`echo $FILE | sed "s,$BASEDIR,,"`
   DESTPATH=${DESTDIR}/$RELPATH
   echo ln \"$FILE\" \"$DESTPATH\"
done

1 个答案:

答案 0 :(得分:1)

通常使用find这样做是个坏主意 - 你基本上依赖于在空格上分隔文件名,而实际上所有形式的空格在大多数UNIX系统上都是有效的文件名。查找本身能够在找到的每个文件上运行单个命令,这通常是更好的选择。我建议做这样的事情(我为了简单起见使用了几个脚本,不知道在一个中完成这一切是多么容易):

main.sh:

BASEDIR="$1" #I tend to quote all variables - good habit to avoid problems with spaces, etc.
DESTDIR="$2"
find "$BASEDIR" -type d -exec ./handle_file.sh \{\} "$BASEDIR" "$DESTDIR" \; # \{\} is replaced with the filename, \; tells find the command is over
find "$BASEDIR" -type f -exec ./handle_file.sh \{\} "$BASEDIR" "$DESTDIR" \;

handle_file.sh:

FILENAME="$1"
BASEDIR="$2"
DESTDIR="$3"
RELPATH="${FILENAME#"$BASEDIR"}" # bash string substitution double quoting, to stop BASEDIR being interpreted as a pattern
DESTPATH="${DESTDIR}/$RELPATH"
if [ -f "$FILENAME" ]; then
  echo ln \""$FILENAME"\" \""$DESTPATH"\"
elif [ -d "$FILENAME" ]; then
  echo mkdir -p \""$DESTPATH"\"
fi

我用一个简单的树来测试它,包括空格,星号,撇号,甚至是文件名中的回车,它似乎都有效。

显然删除了转义的引号和" echo" (但保留真实的引号)以使其适用于真实。