Reputation: 1485
Is there a difference between:
$ bash ~/script.sh
and:
$ cat ~/script.sh | bash
They seem to behave slightly differently, and I can't quite figure out what is going on. My script.sh
contains several lines of bash, but it seems to abort early when I pipe it into bash (but runs to completion when I run the script directly).
What's the difference in running the script in these two ways?
Furthermore, when I use <
, the behavior is the same as the first example (runs to completion):
bash <( ~/script.sh )
The script is along the lines of
set -eux
ssh CLUSTER_0_SERVER_0 "do_something" || ssh CLUSTER_0_SERVER_1 "do_something"
ssh CLUSTER_1_SERVER_0 "do_something" || ssh CLUSTER_1_SERVER_1 "do_something"
Upvotes: 3
Views: 12671
Reputation: 21435
Your ways of running the same script are all different in semantics.
See for example this simple script:
#!/bin/bash
echo $$
ssh 127.0.0.1
echo $$
Running it directly will execute all of the lines inside and both echo
invocations will print the same PID: everything is a single process which runs the commands inside the script, one by one.
Running it via cat ./script.sh | bash
creates two different processes in the beginning: one for doing the cat
and one for bash
. However, when the bash interpreter reads and executes the ssh
command you get an error (if the ssh is not configured to not print it):
Pseudo-terminal will not be allocated because stdin is not a terminal
and then you get a login to the machine and it leaves immediately, killing the current process. Thus, the second value is a different PID. In your case, you have two ssh
commands linked by a conditional operator. However, since after the first one the interpreter is killed there is no way the second command will be executed. That's why you'll get only the *_SERVER_0
ssh
commands executed.
The third case works but only by mistake. The <( cmd )
construct means executing cmd
and passing its output as a file argument to the caller. In your case, the script doesn't print anything so that's why you don't see any error. Running the example script you'll get errors like:
/dev/fd/63: line 1: 29355: command not found
The fourth case (suggested in the comments) bash < script
is just the same as cat script | bash
.
The proper way to run bash scripts is via bash script
or ./script
(and shebang). If you want to run the instructions in the same process you can also use . script
(source
) All others might work or not, depending on some lucky side effects (in general they should not work).
Upvotes: 5