为什么通过“sh *.sh”函数运行的脚本与“./*.sh”不同?

use*_*912 2 command-line bash

我正在使用 Ubuntu 15.10。我注意到一个奇怪的问题。

rsync使用--exclude={}选项运行嵌入在 shell 脚本中的命令(以 root 身份)时,rsync工作并排除路径,因为当我以 root 身份启动它时

./rBackup.sh
Run Code Online (Sandbox Code Playgroud)

但是,当我通过 root 运行它时

sh rBackup.sh
Run Code Online (Sandbox Code Playgroud)

exclude 目录选项不会延续,并且在备份它正在备份的驱动器时无限循环 in /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
Run Code Online (Sandbox Code Playgroud)

hee*_*ayl 5

当你跑

sh rBackup.sh
Run Code Online (Sandbox Code Playgroud)

脚本rBackup.shsh( dash)运行,它不支持大括号扩展。

另一方面,当你做

./rBackup.sh
Run Code Online (Sandbox Code Playgroud)

然后#!/bin/bash第一行指定要使用的确切解释器。它恰好bash支持大括号扩展。

如果您没有在 shebang 行中包含有效的可执行文件,那么您只是在您所在的当前 shell 下运行脚本(或sh取决于 shell 实现)。

示例:来自bash

$ cat scr.sh 
echo {bar,spam}

$ sh scr.sh 
{bar,spam}

$ ./scr.sh 
bar spam
Run Code Online (Sandbox Code Playgroud)

我的登录外壳是zsh. 这里有几点需要注意:

  • zsh,./scr.sh被发送到sh( dash)

  • 在 at 时bash./scr.sh被发送到bash

  • 在 at 时ksh./scr.sh被发送到ksh

  • dash,./scr.sh被发送到sh( dash)


为了安全起见,请始终尝试使用shebang(脚本的第一行)提及所需的解释器,例如:

#!/usr/bin/env bash
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

1297 次

最近记录:

9 年,7 月 前