Search code examples
linuxbashshellsudo

What shell does sudo use


My apologies as this has to be a question others have asked but it seems google proof. I'm trying to figure out what shell is being invoked as I have met an inconsistency. My script doesn't work if I sudo, but does work if I sudo bash. Yet when I sudo echo $0, it says bash.

cpu=$(cat /proc/cpuinfo | grep Revision | cut -d' ' -f 2-);
if [[ "a22082" = $cpu || "a02082" = $cpu ]]; then
    echo 'do stuff';
fi

If I specify the command interpreter with #!/bin/sh it still fails but being more specific #!/bin/bash it does.

I (now) know that [[ is bash specific but despite the response it doesn't seem like sudo's default shell is bash.


Solution

  • Short answer: There is no default interpreter. Your script needs a shebang line #!/bin/bash at the top.

    Long answer: sudo does not run a shell. It runs the command you pass it directly, no intermediate shell. If you want a shell you need to explicitly pass it one.

    sudo echo $0
    

    This command is misleading due to $0 being expanded by your shell before sudo is called. It's printing your current $0, not the value of $0 inside the sudo'd environment.

    Let's compare some commands:

    • sudo ls

      This executes the /bin/ls executable directly. There's no shell involved. The following commands will show when the distinction comes into play.

    • sudo ls /root/*

      The current shell expands the glob. If you can't access /root/ then the glob isn't expanded and you get ls: cannot access /root/*: No such file or directory.

    • sudo 'ls /root/*'

      This attempts to execute a program called ls /root/*. Literally, it's named * in the root sub-directory of ls  (ls with a trailing space). It fails with sudo: ls /root/*: command not found.

    • sudo ls '/root/*'

      This runs /bin/ls and passes it the literal string /root/*. There's no glob expansion. It fails with ls: cannot access /root/*: No such file or directory.

    • sudo bash -c 'ls /root/*'

      This executes /bin/bash and has it interpolate the ls /root/* command-line, expanding the glob. This one, finally, works, because we have an explicit shell to expand the glob, and we're doing the expansion within sudo instead of outside of it.