3

Given a shell script file that begins as

#!/bin/bash

# (bash script here),

and has been chmod +xed, is there any difference in running ./script and bash script from the command-line?

wchargin
  • 1,091

4 Answers4

8

It depends on your $PATH. ./script will run /bin/bash script. bash script will use whatever bash comes first in your path, which isn't necessarily /bin/bash, and could be a different version of Bash.

cjm
  • 27,160
  • Okay, that makes sense; is there a "preferred" or "recommended" way to do it? I've always seen ./script but recently saw a couple answers on Unix.SE using bash script. – wchargin Nov 11 '13 at 21:49
  • 1
    The more generic "bash script" version is useful if you are testing against different versions of bash. Imagine ~/bin is first in $PATH and ~/bin/bash symlinks to ~/bin/bash_versions/4.2.45/bash or ~/bin/bash_versions/4.1.11/bash or other versions. If you tried to do the same thing with /bin/bash, you would need to be root (to alter /bin) and would undoubtedly eventually break something in your distro. – Joe Atzberger Nov 11 '13 at 22:48
  • 2
    @WChargin People sometimes write bash script instead of ./script in usage instructions so that they don't need to explain how to give script execution permissions or what to do on the (non-Linux) systems where bash isn't in /bin. – Gilles 'SO- stop being evil' Nov 12 '13 at 00:10
  • @Gilles Excellent; that clears it up. Thanks. – wchargin Nov 12 '13 at 02:35
4

There are two differences:

  • ./tryit.sh will not run if bash is not located in /bin, but bash tryit.sh will run if bash is anywhere on your PATH. This is because ./tryit.sh will use the shell from the bang path (/bin/bash), but bash tryit.sh will use the first bash shell on the PATH.
  • ./tryit.sh will not run if the execute bit is not set, but bash tryit.sh will run the script. You have excluded this case by specifying the bit has been set. Some edits may clear the bit causing a working command to start failing.

The command bash tryit.sh invokes bash telling it that the commands to be executed are found in the file tryit.sh. Many programs such as awk, perl, python, bash, sh, ksh, work in this manner. This is a standard idom for Unix programs that process command files.

BillThor
  • 8,965
  • 1
    Can you please point me to something that elaborates on your second point? "./tryit.sh will not run if the execute bit is not set, but bash tryit.sh will run the script". Documentation? Articles? Anything. – Slothworks Aug 13 '15 at 07:05
  • @Slothworks FWIW, source tryit.sh won't care about the status of the +x bit either :) In any case, I think the source way is much better than using the fairly huge bash binary itself to run a script which lacks the +x flag. I've never had a situation when I had to (mis)use bash as a trigger to run such non-executable script. – syntaxerror Aug 13 '15 at 08:32
  • @syntaxerror I am aware of source being able to do that, with its set of nuances of course. I merely wish to look at some content that expands on @BillThor's second point; maybe elaborating (more than the single line in the answer itself) on why bash can run a script which lacks the +x flag etc. – Slothworks Aug 13 '15 at 09:25
  • In a nutshell: IMO using bash itself (instead of its built-in commands) for running a script I'd almost compare to "committing a crime." – syntaxerror Aug 13 '15 at 09:29
  • @syntaxerror See my update. – BillThor Aug 13 '15 at 18:22
-2

They are subtly different and easy to make a mistake.

The one you should use (which I'll write in two forms)

./script
bash ./script

My reasoning is that this is explicit, in case you've changed directory.

non explicit forms

script
bash script

Are less safe. bash script will search the current directory then the directories in the PATH environment variable, script by itself is searched only in PATH directories. Running a different command than intended could clobber your files.

X Tian
  • 10,463
  • 3
    You seem to be answering a different question. The OP is not asking about the difference between bash script and bash script but bash ./script and ./script. If you run ./script, your $PATH is irrelevant, since you are giving a full path, the shell will never look for script in your $PATH variable. – terdon Nov 11 '13 at 16:43
  • Upon re-reading I think you are correct, there's probably a typo in his question " is there a difference between ./script and bash script" which is what I answered – X Tian Nov 11 '13 at 16:52
  • 1
    @XTian No, there isn't a typo - the difference between ./script and bash script is exactly what I'm asking. However, I fail to see how you've answered this. Also, you seem to imply in your answer that simply writing script will "look in the current directory for script ... then search through the ... PATH" if it doesn't find it; unless I'm mistaken, I don't believe this is the case. Running script will only find a file on the path: $ touch script; $ script; bash: script: command not found. – wchargin Nov 11 '13 at 21:54
  • @WChargin Ok, so there isn't a typo, my bad. I'm only trying to warn you that bash ./script is much safer than bash script. In the latter, if script is not found in your cwd, then the PATH is searched, and if found will be used to read commands from (it doesn't even have to e executable!). There's no difference between ./script vs bash ./script but a big difference when ./ is omitted. ps I sometimes come across people with dot in their PATH, you are correct, bash doesn't search for commands there normally. – X Tian Nov 12 '13 at 13:59
-2

If I remember correctly from the top of my head, the following two are identical:

$ ./script

and

$ source script

So using the ./ "command" will in fact invoke source under the hood, which on its part is a bash builtin command. Or, in another interpretation they might be called aliases of each other. However: The first invocation requires you, the user, to set the +x (=executable) flag with chmod for owner or group, otherwise you will get a "permission denied" error, whilst execution using the source command is even possible without the +x flag. So the latter will sometimes be your life-saver whenever you want to run a bash script off an NTFS-formatted pendrive, for instance, since chmod cannot work there.

I think that will answer your question as well in some way.

Because, for that reason, bash script and source script cannot be exactly the same; the one is calling the bash program itself with your script given as a parameter, whilst the other is calling one of bash's builtin commands with your script as a parameter. Though the result will most probably be the same (at least in everyday use), the ways how to get there are somewhat different in both cases.

syntaxerror
  • 2,246
  • 3
    Um, *no.  .* script and source script are equivalent in bash and the other shells in which . and source mean the same thing.  ./script runs the script in a separate process.  . script runs the script in the current shell process, which (a) might not be bash, and (b) lets the script alter your main shell's environment.  This requires that you have read permission to the script.  ./script runs the script in a new process, using the interpreter specified in the shebang, provided the user has both read and execute permission. – Scott - Слава Україні Aug 13 '15 at 08:41
  • Wait a moment...I have never written anything about the . command. That's yet another pair of shoes. I only mentioned ./script and source script in my answer, but not . ./script. Yes it can be confusing at times. Ah, and big thanks for the downvote. :P Yay, that felt so refreshing. – syntaxerror Aug 13 '15 at 09:03