mai*_*ash 6 bash shell-script mv
在我的 Bash 脚本中,我有这一行:
mv -f $HOME_DIR/$dir $HOME_SAVE/BACKUP
Run Code Online (Sandbox Code Playgroud)
问题是当$dir为空(无$dir目录)mv命令移动目录时$HOME_DIR。我们只想移动$dir目录。
我怎样才能避免这种情况?
我可以用这个:
ls $HOME_DIR | wc -l
# and verify if the number is -gt 1
Run Code Online (Sandbox Code Playgroud)
但这不是一个优雅的解决方案。
你应该使用:
mv -f -- "$HOME_DIR/${dir:?}" "$HOME_SAVE/BACKUP/"
Run Code Online (Sandbox Code Playgroud)
扩展将失败,脚本退出,如果$dir的值为空,则会向 stderr 发出一条错误消息。
您甚至可以指定打印的消息,如:
mv -f -- "$HOME_DIR/${dir:?\$dir is UNSET or NULL!}" "$HOME_SAVE/BACKUP/"
Run Code Online (Sandbox Code Playgroud)
或者 - 不那么最终 - 您可以指定默认值和/或替代值,$dir这些值仅在未:-设置或为空或:+使用类似形式设置而不为空时才应用。所有这些例子——上面和下面——代表了几个标准 POSIX 指定的参数扩展形式中的一些。
在下面的示例中,当$dir设置而不为空时,第一部分评估为您的源目录,否则为任何内容,第二部分评估为其值(如果有),但如果没有,则评估为您的目标目录。mv当它的第一个和第二个参数命名相同的路径名时指定为失败,因此根本没有移动。
mv -f -- "${dir:+$HOME_DIR/}${dir:-$HOME_SAVE/BACKUP/}" "$HOME_SAVE/BACKUP/" 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
虽然我认为这可能是矫枉过正:
mv -f -- "$HOME_DIR/$dir" ${dir:+"$HOME_SAVE/BACKUP/"} 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
...应该也一样 -mv不能移动任何地方。请注意,在符合 POSIX 的 shell 中,即使在花{}括号内的引号也用于保护扩展,因为在这种情况下,它不是$dir扩展了 的值,而是扩展了${dir:+word} word的值。将它们放在大括号内用于将扩展评估为根本没有 - 甚至不是空字符串 - 当${dir}未设置或为空时。这可能真的无关紧要 - 我相当确定空文件名几乎在任何地方都是无效的 - 但这是我通常的做法。${dir:-"word"}但是,这样做并不安全- 在这种情况下,您将获得${dir}'s unquoted extension 或word' squoted extensions 。
您还可以-i选择mv仅在$dir为 null 时调用nteractive 选项,例如:
mv "-i${dir:+f}" -- "$HOME_DIR/$dir" "$HOME_SAVE/BACKUP/" </dev/tty
Run Code Online (Sandbox Code Playgroud)
...所以你至少不会意外覆盖.../BACKUP 中的任何文件,除非有人先在终端按下y (或其他)。
POSIXly:
[ -n "$dir" ] && mv -f -- "$HOME_DIR/$dir" "$HOME_SAVE/BACKUP"
Run Code Online (Sandbox Code Playgroud)
或者:
[ -d "${dir:+$HOME_DIR/$dir}" ] && ...
Run Code Online (Sandbox Code Playgroud)