Blank first line of shell script: explain behavior

2020-04-11 11:05发布

问题:

I have two very simple scripts, differing only by the presence of a blank first line:

$ cat test.bash
#!/bin/bash
echo ${UID}
$ cat test_blank.bash

#!/bin/bash
echo ${UID}

Now I run then, with and without nice:

$ ./test.bash
1060

$ ./test_blank.bash
1060

$ nice ./test.bash
1060

$ nice ./test_blank.bash

Please explain why, in the final case, the UID variable is unset. The behavior is the same when replacing nice with sudo or nohup.

回答1:

Observe:

$ bash test_blank.bash
1060
$ dash test_blank.bash

bash produces output but dash, which is the default sh on debian-like systems, does not. This is because bash sets UID but dash does not. (POSIX does not require a shell to set UID.) So, the question becomes which shell executes the script.

When bash sees ./test.sh, it (bash) runs the script. When another command, such as nice, receives the script as an argument and the script does not have a valid shebang as the first line, then the default shell, likely dash, is run.

If you want UID in dash, or any other shell that does not provide it, use the id command:

UID=$(id -u)

Finding out which shell is running a script

To see which shell is running a script, use:

$ cat test2.sh

#!/bin/bash
ps $$
echo UID=${UID}

Under bash:

$ ./test2.sh
  PID TTY      STAT   TIME COMMAND
 1652 pts/12   S+     0:00 bash -rcfile .bashrc
UID=1060

If we invoke it using nice, by contrast, we can see that it is running under /bin/sh and the UID variable is not assigned:

$ nice test2.sh
  PID TTY      STAT   TIME COMMAND
 1659 pts/12   SN+    0:00 /bin/sh test2.sh
UID=


标签: bash shell