临时更改 /bin/sh 链接

cor*_*win 9 command-line bash sh

我有一个软件需要/bin/shBash,但对于 Ubuntu,默认是 Dash,我想保持默认;我不想将其永久更改为 Bash。

有没有办法只为正在运行的终端会话更改它?所以在这个终端中运行的程序会看到/bin/sh链接到 bash 但系统的其余部分仍然会看到 Dash?或者我可以欺骗软件将/bin/sh其视为 Bash,即使它不是?

这个软件不是我写的,用它来/bin/bash代替/bin/sh并不是一个真正的选择。

Ser*_*nyy 14

如果它是一个脚本,只需将脚本称为

bash scriptname.sh
Run Code Online (Sandbox Code Playgroud)

根本不需要更改链接。

对于已编译的可执行文件,您可以使用 chroot 路由:

mkdir rootfs
cp -a /usr rootfs/
cp -a /lib rootfs/
cp -a /lib64 rootfs/
cp /bin/bash  rootfs/bin/sh
cp yourprogram  rootfs/
sudo chroot rootfs  sh
Run Code Online (Sandbox Code Playgroud)

然后运行你的程序或 sudo chroot rootfs /yourprogram


但是,在实践中没有理由不能将其/bin/bash用作/bin/sh. 事实上,在 6.10之前, Ubuntu 使用/bin/bashas /bin/sh,然后由于/bin/shPOSIX 的实现更快、更精简/bin/sh(也就是说,它遵循 POSIX 标准,关于类 Unix 操作系统实用程序和操作系统的行为方式以及实现它们的一些内部结构),并且由于可移植性原因。我强烈建议您阅读 Gilles 的回答以及有关如何/bin/dash发生的历史记录。至于兼容性,为dash使用 POSIX 功能编写的脚本将在bash默认 shell 下运行,非常好。通常,反过来会导致问题-bash具有 不需要的功能/bin/sh,例如<<<语法或数组。

此外,有问题的命令可能是用 RHEL 或 CentOS 编写的,它确实/bin/bash用作 的符号链接/bin/sh,暗示了两件事:它们可能针对特定的操作系统并且不遵守 POSIX 原则。在这种情况下,检查命令需要哪些其他内容也是一个好主意,因为如果它真的是用另一个操作系统编写的,那么您可能会遇到更多的问题,而不仅仅是重新链接/bin/sh

  • +1,最好创建硬链接而不是副本(通过`ln` 或`cp -l`)。 (3认同)
  • 哈哈。生活可以如此简单:-) (2认同)

mur*_*uru 10

两个答案已经建议 chrooting 和 bind mounts,还有第三个密切相关的选项:mount namespaces使用该unshare程序,您可以创建一个新的挂载命名空间,该命名空间内的挂载不会影响其他命名空间。

例如,在一个终端中,我这样做:

muru|[0] ~ sudo unshare -m /bin/bash
root@muru-1604:~# sudo mount --bind /bin/bash /bin/sh
root@muru-1604:~# /bin/sh --version
GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@muru-1604:~# sudo -iu muru
muru|[0] ~ /bin/sh --version  # propagates
GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Run Code Online (Sandbox Code Playgroud)

而在另一个:

$ /bin/sh --version
/bin/sh: 0: Illegal option --
Run Code Online (Sandbox Code Playgroud)

所以你可以在它自己的挂载命名空间中运行这个不灵活的程序。


Per*_*uck 5

一种可能性是绑定安装单个文件。要做到这一点,你安装的文件/bin/bash只是 /bin/dash这样bash的排序覆盖或隐藏的dash。以下是步骤(包括反向):

root@myhost:~# cd /bin

# situation before (bash and dash are different):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root  121432 Jan 25  2018 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# mount /bin/bash over /bin/dash:
root@myhost:/bin# mount --bind /bin/bash /bin/dash

# situation now (bash and dash are the same):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# Now everything that runs `/bin/sh` in fact uses `/bin/bash`.

# check what the symlink "sh" says:
root@myhost:/bin# sh --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
...

# undo the mount:
root@myhost:/bin# umount /bin/dash 

# situation now (bash and dash are different again):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root  121432 Jan 25  2018 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# check what the symlink "sh" now says:
root@myhost:/bin# sh --version
sh: 0: Illegal option --
Run Code Online (Sandbox Code Playgroud)

不过,我并没有试图mount --bind /bin/bash /bin/sh直接隐藏 符号链接。上述mount招只是让bash和破折号相同的,使得shbash,虽然它指向 dash。此外,这是一个系统范围的解决方案,不仅适用于当前的终端窗口。


我必须承认,这可能有点矫枉过正,简单地临时更改符号链接要容易得多。我只是想展示另一种可能的方式。