xml*_*lmx 11 linux fedora bash shell sh
bash4.3 # pwd
/bin
bash4.3 # ll sh
lrwxrwxrwx. 1 root root 4 May 17 22:22 sh -> bash
bash4.3 # ll bash
-rwxr-xr-x. 1 root root 1072056 May 17 22:22 bash
bash4.3 # bash
bash4.3 # sh
sh-4.3#
Run Code Online (Sandbox Code Playgroud)
我的操作系统是 fedora 24(默认 GNOME 版本)。
从例子中我们可以知道: 下/bin
,bash
是一个二进制可执行文件;sh
是一个软链接bash
。
因此,据我所知,type bash and press enter
应该产生与type sh and press enter
.
当 I 时type bash and press enter
,我得到[root@localhost bin]#
了预期的结果。
但是,如果我type sh and press enter
,我出人意料地得到sh-4.3#
。
原因是什么?
Joh*_*024 25
这是一个记录在案的功能。
如果您通过名为 的符号链接运行 bash sh
,bash 将以sh
兼容模式启动。
来自man bash
:
如果使用名称 sh 调用 bash,它会尝试尽可能模仿 sh 历史版本的启动行为,同时也符合 POSIX 标准。当作为交互式登录 shell 或带有 --login 选项的非交互式 shell 调用时,它首先尝试按顺序从 /etc/profile 和 ~/.profile 读取和执行命令。--noprofile 选项可用于禁止此行为。当作为一个名为 sh 的交互式 shell 被调用时,bash 查找变量 ENV,如果它被定义,则扩展它的值,并使用扩展的值作为要读取和执行的文件名。由于作为 sh 调用的 shell 不会尝试从任何其他启动文件读取和执行命令,因此 --rcfile 选项无效。使用名称 sh 调用的非交互式 shell 不会尝试读取任何其他启动文件。当作为 sh 调用时,bash 在读取启动文件后进入 posix 模式。
如果是ac程序,可以检查argv[0]
。如果是 shell 或 perl 脚本,它可以检查$0
.
例如,让我们考虑这个简单的 shell 脚本:
$ cat utc
#!/bin/sh
case "${0##*/}" in
utc) date -u ;;
et) TZ=US/Eastern date ;;
esac
Run Code Online (Sandbox Code Playgroud)
$0
是调用脚本的名称。 ${0##*/}
是在删除任何目录名称的情况下调用脚本的名称。
让我们创建这个符号链接:
ln -s utc et
Run Code Online (Sandbox Code Playgroud)
所以,utc
与et
这两种运行相同的可执行文件,但它们提供了不同的结果。当作为 运行时utc
,它输出世界时。当作为 运行时et
,输出美国东部时间。例如:
$ utc
Wed Jul 20 18:14:18 UTC 2016
$ et
Wed Jul 20 14:14:20 EDT 2016
Run Code Online (Sandbox Code Playgroud)