临时更改/ bin / sh链接


9

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

有没有一种方法可以仅针对正在运行的终端会话进行更改?因此,在此终端中运行的程序将看到已/bin/sh链接到bash,但系统的其余部分仍将看到Dash?还是可以欺骗该软件以使其显示/bin/sh为Bash(即使不是)?

我不是写这个软件,/bin/bash而是破解它而/bin/sh不是真正地选择。


2
您可以临时更改它-但(AFAIK)不能将范围限制为单个终端会话。例如,请参见/ bin / sh是不指向/ bin / bash的符号链接
steeldriver


7
无论您做什么,也请将此报告为有关软件的错误。因为假设/bin/shbash 一个错误,它会导致实际问题(如你发现了)。如果没有人抱怨,它可能永远都不会改变。
marcelm

1
@SergiyKolodyazhnyy如果该错误不会在他们支持的唯一平台上引起问题,那么他们可能可以摆脱它。虽然这仍然是一个错误。
marcelm

1
该软件是Petalinux,由一家名为Xilinx的“小型”公司发行,根据文档说明,Ubuntu 16.04(以及CentOS和RHEL)均受支持,因此我将其称为错误。
corwin

Answers:


10

已经有两个答案建议使用chroot和绑定挂载,还有第三个紧密相关的选项: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.

而在另一个:

$ /bin/sh --version
/bin/sh: 0: Illegal option --

因此,您可以在其自己的安装名称空间中运行该不灵活的程序。


14

如果是脚本,只需将该脚本称为

bash scriptname.sh

根本不需要更改链接。

对于编译的可执行文件,您可以使用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

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


但是,在实践中,没有理由不能将您/bin/bash用作的符号链接/bin/sh。实际上,在6.10之前, Ubuntu使用/bin/bashas /bin/sh,然后由于/bin/shPOSIX的实现更快,更精简而进行了切换/bin/sh(也就是说,它遵循POSIX标准,以了解类Unix操作系统实用程序和OS的行为方式,以及并出于可移植性原因)。我强烈建议您阅读Gilles的答案,以获取有关其产生方式的历史记录/bin/dash。至于兼容性,为dash使用POSIX功能而编写的脚本将在bash默认情况下完美运行。通常,这是导致问题发生的另一种方法-bash具有不需要的功能/bin/sh,例如<<<语法或数组。

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


2
大声笑。生活可以这么简单:-)
PerlDuck

1
您赢得了我的支持:)
Joshua Besneatte

@JoshuaBesneatte谢谢!很高兴您发现我的回答有用
Sergiy Kolodyazhnyy

3
+1,最好创建硬链接而不是副本(通过lncp -l)。
大卫·佛斯特

1
考虑mount --rbind --make-rslave而不是考虑cp -r。也可以设为只读。还sudo chroot以root用户身份运行脚本,这可能不是最佳选择。
Roman Odaisky

5

一种可能是单个文件的绑定安装。为此,只需将文件挂载这样的Cover或hides上即可。这是步骤(包括相反的步骤):/bin/bash /bin/dashbashdash

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 --

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


我必须承认,这可能是过大的,只是临时更改符号链接要容易得多。我只是想展示另一种可能的方式。


1

您应该能够使用别名为当前会话更改它。在终端中运行命令之前:

alias sh=bash

这将是临时的,并且仅在从其执行的终端中处于活动状态。

但是:如果您的脚本使用绝对路径,则此方法将无效。

这样的主意不错,但是如果软件使用明确的路径名直接调用/ bin / sh,它将无法正常工作。无论如何,基于这样的假设,该软件的设计似乎并不是很恰当。如果我必须使用它,我可能会从准备并重置适当环境的脚本中运行它。–钒

不幸的是,“入侵”脚本可能是您唯一的选择。每个@vanadium的convo,您可以创建一个包装器脚本,如下所示:

#!/bin/bash
sudo ln -sf /bin/bash /bin/sh
/run/my/script
sudo ln -sf /bin/dash /bin/sh

但是,在脚本运行期间,您最好希望您的系统上没有任何内容明确要求破折号。


3
这样的好主意,但是如果软件使用显式路径名直接调用/ bin / sh,它将无法正常工作。无论如何,基于这样的假设,该软件的设计似乎并不是很恰当。如果必须使用它,我可能会从准备并重置适当环境的脚本中运行它。

我很想知道您将如何准备环境。你会用chroot吗?
Joshua Besneatte '18

我没有那么雄心勃勃的想法。我只是在考虑一个脚本,该脚本会暂时将sh链接到bash并在完成后重置。我认为,这个问题的主要问题在于有关的“软件”。

如果在移动符号链接时还需要破折号,那该怎么办....像开始时的ln -sf / bin / bash / bin / sh和完成时的ln -sf / bin / dash / bin / sh一样?
Joshua Besneatte

如果更改了链接,大多数其他进程可能会很乐意使用bash而不是破折号。是的,虽然徒劳无功,但为了模仿当前情况,我会建立相对链接,即“ cd / bin; ln -sf bash sh”,但这可能是一个纯粹的细节,实际上并不重要。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.