24

I am installing a huge program, which has its resources as an rpm file. It stuck at the line of

#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]

Apparently, sh work for bash in Red Hat Linux with this syntax, but it gives the error of unexpected operator in Ubuntu.

I cannot change the script to bash as the script comes from the rpm package. I can extract and repack the rpm package, but there might be many of such scripts.

Is there a way to change the shell default to treat #!/bin/sh as bash or anything else, which can handle the [ operator?

Googlebot
  • 1,959
  • 3
  • 26
  • 41
  • 5
    The only thing wrong is the == that should be =. That, and that the variable expansions should be double quoted. – Kusalananda May 08 '18 at 11:29
  • 4
    [ is not an operator, but a builtin command that is called test. The unexpected operator is == and this should be replaced by = because it is not POSIX compliant. – schily May 08 '18 at 11:34
  • The second only thing that is wrong is that $SCITEGICPERLHOME should be quoted. – l0b0 May 08 '18 at 19:35
  • 13
    You should complain to the author of the program. If they use #!/bin/sh, they should make sure they only use POSIX shell features, not bash extensions. This programmer is very sloppy. He should either fix his code or use #!/bin/bash. – Barmar May 08 '18 at 19:44
  • For people wondering about other similar issues here is a list of "Bashisms". Also see this question. – Captain Man May 08 '18 at 23:00
  • Huh, do some distributions still use bash as sh by default?! – jarno Apr 30 '21 at 21:58

2 Answers2

53

Up to Ubuntu 22.04 included (and Debian 11 included), you can switch sh to bash (instead of dash, the default) by reconfiguring dash (yes, it’s somewhat counter-intuitive):

sudo dpkg-reconfigure dash

This will ask whether you want dash to be the default system shell; answer “No” (Tab then Enter) and bash will become the default instead (i.e. /bin/sh will point to /bin/bash).

Since Ubuntu 22.10 and Debian 12, this is no longer supported; if you want to switch /bin/sh to /bin/bash, you’ll have to symlink it manually. See Gilles’ answer for details.

Stephen Kitt
  • 434,908
  • 1
    Your solution is indeed the most reasonable one, but I accepted another answer because of detailed descriptions clarifying the issue. Sorry for any inconvenience. – Googlebot May 08 '18 at 11:52
  • Debian bookworm has removed this method: "From DebianSqueeze to DebianBullseye, it was possible to select bash as the target of the /bin/sh symlink (by running dpkg-reconfigure dash). As of DebianBookworm, this is no longer supported." See https://wiki.debian.org/Shell. Would expect Ubuntu to follow soon. – xuhdev Jul 18 '23 at 06:58
40

There are multiple programs that implement the language of /bin/sh. On Ubuntu, /bin/sh is dash, which is designed to be fast, to use a small amount of memory, and doesn't support much more than the minimum expected from /bin/sh. On RHEL, /bin/sh is bash, which is slower and uses more memory but has more features. One of these features is the == operator for the [ conditional syntax. Dash supports [, which is a basic sh feature, but it doesn't have the == operator which is a bash (and ksh and zsh) extension.

You can switch your system to using bash. On Ubuntu, /bin/sh is a symbolic link to dash. You can make it a symbolic link to bash instead. Current versions of Debian and Ubuntu (and derivatives) make this an installation option of dash. To change it, run

sudo dpkg-reconfigure dash

and answer “yes” to keep dash as /bin/sh or “no” to switch to bash.

You can keep bash as /bin/sh, but it'll make your system a bit slower. It's even conceivable that some system script is incompatible with bash, although that's unlikely since bash is mostly a superset of dash.


For distributions which don't have an interface to choose between implementations of /bin/sh, here's how to switch to bash.

sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh

Keep a terminal open and check that you can still run some sh scripts after that. If you mess up this command, it'll make your system unusable. (By the way, the reason I used the multiple commands above rather than the straightforward-looking sudo ln -sf bash /bin/sh is that ln -sf is not atomic. In the admittedly unlikely case your computer crashed during this operation, you'd need to boot from rescue media to restore it. In contrast, mv is atomic.)

To restore dash as /bin/sh:

sudo ln -s dash /bin/sh.dash
sudo mv /bin/sh.dash /bin/sh

Note that if sh is /bin/bash by default on your distribution, switching to dash may cause scripts to fail, because bash has many more features than dash. Bash scripts should start with #!/bin/bash, and scripts starting with #!/bin/sh should not use bash-specific features, but distributions that ship with bash as /bin/sh may use bash-specific features in #!/bin/sh scripts that are specific to that distribution (it's ok as long as there's no expectation that users can switch to dash as /bin/sh and there's no expectations that these scripts work on another distribution).

  • In my not so humble opinion, if some script fails when /bin/sh is Bash, it's a bug either in the system (the package with the script), or in Bash's sh-mode. Like Stephen says, the system explicitly allows for setting /bin/sh back to Bash, via dpkg-reconfigure. It's also mentioned as a possibility in the Ubuntu wiki on this matter: https://wiki.ubuntu.com/DashAsBinSh – ilkkachu May 08 '18 at 11:50
  • 5
    @ilkkachu Yes, if a script fails if /bin/sh is bash, it's a bug. However, bugs happen. I recommend sticking to the default if you're not capable and willing to diagnose such bugs because other people have tested it for you. I used dash as /bin/sh before it was officially supported on Debian, but this was a risk I took, knowing that I'd be able to cope if something happened. – Gilles 'SO- stop being evil' May 08 '18 at 11:55
  • Note that manually overridden symlinks will be restored to whatever configuration is stored in debconf the next time dash is updated; admittedly this won’t happen often (if at all, in a given release) for systems running Debian stable. – Stephen Kitt Sep 11 '18 at 19:17