I have a piece of software that requires /bin/sh
to be Bash, but for Ubuntu the default is Dash and I want to keep it the default; I don't want to change it to Bash permanently.
Is there a way to change it only for a running terminal session? So a program running in this terminal will see /bin/sh
linked to bash but the rest of the system will still see Dash? Or can I trick the software to see /bin/sh
as Bash even if its not?
I didn't write this software and hacking it to use /bin/bash
instead of /bin/sh
is not really an option.
If it's a script, just call the script as
No need to change links at all.
For compiled executable you can go chroot route:
And then run your program or
sudo chroot rootfs /yourprogram
However, in practice there is no reason why you can't use
/bin/bash
as a symlink to/bin/sh
. In fact, prior to version 6.10 Ubuntu was using/bin/bash
as/bin/sh
, and then they switched due to/bin/sh
being a much faster, leaner implementation of POSIX/bin/sh
(that is, it adheres to the POSIX standard for how Unix-like operating system utilities and OS should behave and implement some of their internals), and due to portability reasons. I strongly recommend reading Gilles' answer as well for historical notes on how/bin/dash
came about. As for compatibility, scripts written fordash
using POSIX features will run withbash
being a default shell perfectly fine. Usually, it's the other way around that causes problems -bash
has features that aren't required by/bin/sh
, like the<<<
syntax or arrays.Additionally, the command in question is probably written with RHEL or CentOS in mind, which does use
/bin/bash
as a symlink to/bin/sh
, suggests two things: they probably targeted specific OS and didn't adhere to POSIX principles. In that case, it would also be a good idea to check what other things the command requires, since if it's really written with another OS in mind, you might run into more problems than just re-linking/bin/sh
.Two answers already suggest chrooting and bind mounts, and there's a third, closely related option: mount namespaces. Using the
unshare
program, you can create a new mount namespace, and mounts within this namespace won't affect other namespaces.For example, in one terminal, I do:
And in another:
So you could run this inflexible program in its own mount namespace.
One possibility would be a bind mount of a single file. To do this, you mount the file
/bin/bash
just over/bin/dash
sobash
sort of covers or hidesdash
. Here are the steps (including the reverse):I didn't try to
mount --bind /bin/bash /bin/sh
to directly hide the symlink, though. The abovemount
trick just makes bash and dash identical so thatsh
refers tobash
although it points todash
. Also, this is a system-wide solution, not only for the current terminal window.I must confess, this might be overkill and simply changing the symlink temporarily is far easier. I just wanted to show another possible way.
You should be able to change it for just the current session by using an alias. Before running your command in the terminal:
This will be temporary and only active in the terminal it was executed from.
HOWEVER: This will NOT WORK if your script uses absolute paths.
Unfortunately, "hacking" the script might be your only option. Per convo with @vanadium, you could create a wrapper script like this:
However, during the duration of your script, you better hope nothing on your system explicitly requires dash.