The question is published on by Tutorial Guruji team.
I have a bunch of shell scripts which incorrectly assume /bin/sh
to be equivalent to /bin/bash
. E.g., they have the #!/bin/sh
shebang, but use the source
command instead of .
(dot).
I run Ubuntu 16, where /bin/sh
links to dash
, and thus bash-isms are not supported.
I need to run the scripts periodically. Also, from time to time I will need to update them from the original author, who is not into fixing this particular bug. I would like to avoid fixing all these files (there are a bunch of them, they are not mine, and I’ll loose all the changes after update). Also, I would like to avoid making global changes to system, since it might potentially break other scripts.
Is there a way to somehow create a (temporary or not) environment with /bin/sh
pointing to bash, to be used for these scripts, while not touching the global system /bin/sh
?
Answer
I’ve managed to achieve somewhat close to what I initially wanted by using mount namespaces. (My original solution used unionfs as well, but as it turned out it’s not needed at all). It is used to bind-mount /bin/bash
to /bin/sh
for a limited set of processes. The short procedure to set up a new shell, where sh
is bash
, is described below.
First we start new shell with an isolated mount namespace:
sudo unshare -m sudo -u user /bin/bash
And then in the new shell we bind-mount /bin/bash
to /bin/sh
:
sudo mount --bind /bin/bash /bin/sh
That’s it!
Let’s see what we’ve got in this shell:
user@ubuntu:~$ /bin/sh --version GNU bash, version ... user@ubuntu:~$ diff -s /bin/sh /bin/bash Files /bin/sh and /bin/bash are identical
But if running in another shell:
user@ubuntu:~$ /bin/sh --version /bin/sh: 0: Illegal option -- user@ubuntu:~$ diff -s /bin/sh /bin/bash Binary files /bin/sh and /bin/bash differ user@ubuntu:~$ diff -s /bin/sh /bin/dash Files /bin/sh and /bin/dash are identical