Bash – How is running a script like an executable different from running it by a shell explicitly

bash

  1. From A Practical Guide to Linux Commands, Editors, and Shell
    Programming By Mark G. Sobell

    Although you can use bash to execute a shell script, this technique causes the script to run more slowly than giving yourself
    execute permission and directly invoking the script.

    Why is that?

  2. How is running a script like an executable different from running it
    by a shell explicitly?
  3. Do both follow the same steps as:

    A command on the command line causes the shell to fork a new process,
    creating a duplicate of the shell process (a subshell). The new
    process attempts to exec (execute) the command. Like fork, the exec
    routine is executed by the operating system (a system call). Because
    the command is a shell script, exec fails. When exec fails, the
    command is assumed to be a shell script, and the subshell runs the
    commands in the script. Unlike a login shell, which expects input from
    the command line, the subshell takes its input from a file—namely, the
    shell script.

Best Answer

Assuming that the script is a Bash script (i.e. it begins with #!/bin/bash), then the author is wrong on this point. When you run a shell script directly, the kernel sees the #!/bin/bash line at the beginning, then runs that line with the script's filename as a parameter, i.e. /bin/bash myscript.sh. In other words, the kernel is doing exactly what you would do to pass it to a shell explicitly.

Now, if the script begins with #!/bin/sh instead of #!/bin/bash, then there's another possibility. Bash can provide /bin/sh, but it doesn't have to. It also prioritizes features over size or speed. If a smaller, faster shell is your /bin/sh, then running the script directly will use that faster shell, and the script will run faster than it would under Bash.

This happens in practice with Debian-based distributions (e.g. Debian, Ubuntu, Mint). They tend to use a shell called dash to provide /bin/sh instead of Bash, in order to make the boot scripts run faster.

To see what your distribution does, ls -l /bin/sh. It is probably a symbolic link to /bin/bash or /bin/dash, or another shell.

Related Question