在我的 Bash 脚本中,有这样一行:
mv -f $HOME_DIR/$dir $HOME_SAVE/BACKUP
问题是当$dir
为空(无$dir
目录)时,mv
命令移动了目录$HOME_DIR
。我们只想移动$dir
目录。
我怎样才能避免这种情况?
我可以用这个:
ls $HOME_DIR | wc -l
# and verify if the number is -gt 1
但这不是一个优雅的解决方案。
答案1
你应该使用:
mv -f -- "$HOME_DIR/${dir:?}" "$HOME_SAVE/BACKUP/"
$dir
如果的值为空,则扩展将失败,脚本退出,并且将向 stderr 发出错误消息。
您甚至可以指定打印的消息,例如:
mv -f -- "$HOME_DIR/${dir:?\$dir is UNSET or NULL!}" "$HOME_SAVE/BACKUP/"
或者 - 但最终 - 您可以指定默认值和/或替代值,仅当使用类似的形式未设置或为空或设置且不为空时才$dir
应用这些值。所有这些示例(上面和下面)都代表了几种标准 POSIX 指定的参数扩展形式。:-
:+
在下面的示例中,当$dir
设置且不为空时,第一部分评估为您的源目录,否则根本不评估任何内容,第二部分评估为其值(如果有),但如果没有,则评估为您的目标目录。mv
当它的第一个和第二个参数命名相同的路径名时指定失败,因此根本不会移动任何内容。
mv -f -- "${dir:+$HOME_DIR/}${dir:-$HOME_SAVE/BACKUP/}" "$HOME_SAVE/BACKUP/" 2>/dev/null
正如我所想,这可能有点矫枉过正:
mv -f -- "$HOME_DIR/$dir" ${dir:+"$HOME_SAVE/BACKUP/"} 2>/dev/null
...应该也一样 -mv
不能移动任何东西无处。请注意,在符合 POSIX 的 shell 中,即使在花括号内,引号也{}
能起到保护扩展的作用,因为在这种情况下,它不是$dir
的值扩展,而是${dir:+word}
单词的价值扩大了。当${dir}
未设置或为空时,将它们放在大括号内可以将扩展评估为空,甚至不是空字符串。这可能并不重要——我相当确定空文件名在几乎所有地方都是无效的——但这就是我通常这样做的方式。然而,这样做并不安全${dir:-"word"}
- 在这种情况下,您将得到 的${dir}
未加引号的扩展或word
的带引号的扩展。
您还可以选择仅在为 null 时才调用-i
交互式选项,例如:mv
$dir
mv "-i${dir:+f}" -- "$HOME_DIR/$dir" "$HOME_SAVE/BACKUP/" </dev/tty
...因此您至少可以确保不会意外覆盖中的任何文件.../备份没有人先按ay (管他呢)在航站楼。
答案2
POSIXly:
[ -n "$dir" ] && mv -f -- "$HOME_DIR/$dir" "$HOME_SAVE/BACKUP"
或者:
[ -d "${dir:+$HOME_DIR/$dir}" ] && ...
答案3
测试dir
变量是否为空 ( [[ -z $dir ]]
):
[[ -z $dir ]] || mv -t "$HOME_SAVE/BACKUP" "$HOME_DIR/$dir"
答案4
你可以使用这个:
mv -f -- "$HOME_DIR/./$dir" "$HOME_SAVE/BACKUP/"
如果$dir
为空,则会出现“设备或资源繁忙”错误。
然而,这有点像黑客。