6

So I have a simple shell script. What is the difference between the two commands in execution? Is there a preferred way?

$sh -x foobar.sh

OR

$ ./foobar.sh

I found the script executed slower when used with the second command.

3 Answers3

8

The ./foobar.sh file is started by running it with whatever follows the #! in the first line. If this line reads #!/bin/sh -x then it would be identical to the sh -x foobar.sh case (assuming sh is resolved to /bin/sh from the PATH). Maybe it is not started by sh but bash?

The -x flag prints debug info, i.e. every command before it is executed.

3

It depends on the content of the shell script and the used shell. A shell script might contain boilerplate code, called a shebang, like the following:

#!/usr/bin/env bash

The special sequence '#!' instructs the exec() kernel system call to use the program defined right after it as the interpreter. This means that you'll have to look into the file to see what program will be used to execute it if you're using your second style of execution.

Also, from the bash manual (bash -c "help set")

-x  Print commands and their arguments as they are executed.

What your command should be doing - if you are using bash, see note below - is print out each line in your script and execute it. Oddly, this should cause your first command to be slower than the second, instead of the other way around (again: if the interpreter used in both cases is the same). It is much more common to run the shell without the -x, unless, of course, you want to do debugging.

Bottom line: for reasons described here use the shebang with the env program in (as recommended here) and use your second style of execution. This is the most platform independent way of doing things and is the preferred way.

Note: Another thing that complicates things is that the actual interpreter that is behind /bin/sh varies from system to system. In many cases this is actually bash and this is what I have assumed.

  • 1
    Unless I'm mistaken, it's the kernel that interprets the shebang line, rather than any shell. – dhag May 04 '15 at 16:43
  • 1
    You might want to add what a shebang does? Followed by "Why do people rather use #!/bin/env bash over #!/usr/local/bin/bash ? – Hennes May 04 '15 at 16:58
  • My script is a simple bash script which copies certain files, untars a few tarballs and installs the extracted applications. After everything is done, the system is rebooted. – Gaurav Prabhu May 04 '15 at 17:08
  • @dhag: To be honest, I didn't know that. Thanks for teaching me that! I've updated the answer accordingly. – Benjamin B. May 04 '15 at 22:13
1

The first version, with an explicit call to sh will run your script with sh (displaying trace statements, as requested by -x). The second one, which does not specify an explicit interpreter, will respect the shebang line, if any, or default to the shell you are currently running.

For example, if your script has a shebang line of #! /bin/bash, or your shell is bash, then, the second form ./script will cause execution to run bash rather than sh. Since bash is a more full-featured shell than sh, it may have different performance characteristics.

dhag
  • 15,736
  • 4
  • 55
  • 65