我正在使用 Ubuntu 15.10。我注意到一个奇怪的问题。
当我以 root 身份运行rsync
嵌入在 shell 脚本中的命令时,如果带有--exclude={}
选项,rsync
它会正常工作并排除路径,就像我通过 root 身份启动它时一样
./rBackup.sh
但是,当我以 root 身份通过
sh rBackup.sh
排除目录选项不会延续,并且在备份其要备份到的驱动器时会无限循环/media/
。为什么?
编辑 - 这不是 sh / bash 的区别 - 或者不应该是。我有 #!/bin/bash 作为第一行,因此当通过“sh *.sh”运行时,它应该使用 bash 解释器 - 至少理论上如此。
脚本如下:
#!/bin/bash
StandbyMount="/media/astump/sdb2"
mount /dev/sdb2 $StandbyMount
rsync -aAXv --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found,/etc/fstab,/boot/grub/grub.cfg} --delete-before / $StandbyMount
umount $StandbyMount
rm -fr $StandbyMount
答案1
当你跑步时
sh rBackup.sh
该脚本由( )rBackup.sh
运行,但不支持括号扩展。sh
dash
另一方面,当你这样做
./rBackup.sh
然后#!/bin/bash
第一行指定要使用的确切解释器。恰好bash
支持括号扩展。
如果您没有在 shebang 行中包含有效的可执行文件,那么您只是在当前所在的 shell 下运行脚本(或sh
取决于 shell 实现)。
例子:从bash
:
$ cat scr.sh
echo {bar,spam}
$ sh scr.sh
{bar,spam}
$ ./scr.sh
bar spam
我的登录shell是zsh
。以下是一些需要注意的事项:
当 时
zsh
,./scr.sh
正在被发送到sh
(dash
)正在发送
bash
至./scr.sh
bash
正在发送
ksh
至./scr.sh
ksh
当 时
dash
,./scr.sh
正在被发送到sh
(dash
)
为了安全起见,请始终尝试使用 shebang(脚本的第一行)提及所需的解释器,例如:
#!/usr/bin/env bash
答案2
请记住,sh
实际上调用dash
,与 Bash 相比,它是有限的。
正如所观察到的@Serg在对这个问题的评论,花括号可能被解释为 dash 的输入,这就是它无法工作的原因。这就是它失败的原因——Dash 不进行括号扩展。
您可能希望系统使用 Bash 样式解释。如果您使用默认 shell,bash
那么使用 执行脚本./rBackup.sh
,我相信,它将在该正在运行的 shell 中执行。
我认为您期望该脚本将由 Bash 处理,但当您这样做时它将无法工作sh
。
因此,让我们在这里做一些不同的事情:
(1)#!/bin/bash
在开头定义,使其直接执行时使用 Bash。
(2)chmod +x rBackup.sh
- 这将设置可执行位
(3)执行命令仅有的使用./rBackup.sh
或bash ./rBackup.sh
或。这将确保在所有情况下都使用 Bash 来解释该函数;因为它在文件开头bash rBackup.sh
定义了使用(如果您执行了步骤 1),它将在执行脚本时尝试使用 Bash。#!/bin/bash