14

Example one

#!/bin/sh
# purpose: print out current directory name and contents
pwd
ls

Example two

# purpose: print out current directory name and contents
#!/bin/sh
pwd
ls

What is the difference – if I make the first line a comment(#), with #!/bin/sh as the second line, what will happen?

What is meaning of #!/bin/sh ?

Graham Perrin
  • 524
  • 1
  • 10
  • 45
Manikanta
  • 141
  • 1
  • 4
  • It would be easier, if you surrounded scripts with the code tags. Irregular font makes it really confusing... – user1581900 May 13 '13 at 07:32
  • #!/bin/sh specifies the path to the shell that should be used for the script. The similar question was answered here: http://stackoverflow.com/questions/8967902/why-do-you-need-to-put-bin-bash-at-the-beginning-of-a-script-file – user1581900 May 13 '13 at 07:34
  • 2
    possible duplicate...http://stackoverflow.com/questions/7366775/what-does-the-line-bin-sh-mean-in-a-unix-shell-script – Peeyush May 13 '13 at 07:34
  • From https://discourse.trueos.org/t/-/105/36?u=grahamperrin: *if* a shebang with a specific interpreter can appear (and be effective) at somewhere *other* than the first line, then can a script use a sequence of different interpreters? – Graham Perrin Jan 26 '17 at 06:33

2 Answers2

5

Normally a shell script is run by your default shell defined in the /etc/passwd file. But you can define explicitly a program which can run your script.

Unices uses a common method to determine what program needed to run a specific script (man execve(2)). If the script has the proper execute rights set and in a script the first line starts with a #! characters, it will run by the program defined afterwards.

For example if the first line is #!/usr/bin/awk -f then the rest of the file will be passed to the awk program (so it has to use awk syntax). Or if a Makefile starts with #!/usr/bin/make -f then the rest of the file will be passed to make. You can start the script as a normal program and the script can be written in awk or make (or whatever defined) syntax.

If execve does not find #! as the first two character of the file, it will consider as a normal script file and it will run as it is.

So using #! You can determine the script language and You do not need to know what shell is used by the other user using your script. In any other line #! will be interpretered your default shell, which is usually just a comment line.

TrueY
  • 7,360
  • 1
  • 41
  • 46
  • if i give comment(#) in 1st line after #!/bin/sh in 2nd line so what will happen ? – Manikanta May 13 '13 at 07:42
  • @Manikanta: It is a comment line in `sh`, so it will be skipped. On a linux machine `ls -l /bin/sh` is a symbolic link to bash. – TrueY May 13 '13 at 07:47
  • @TrueY `/bin/sh` is definitely not a link to `bash` on all Linux systems, e.g. Debian-based systems switched to `dash` quite a while ago. Also, it is not the shell that looks for the `#!`, the kernel does that. – Adrian Frühwirth May 13 '13 at 11:30
  • @AdrianFrühwirth: Thanks for the comment! You are right. Man page of bash says: "The shell executes the specified interpreter on operating systems that do not handle this executable format themselves." – TrueY May 13 '13 at 14:40
  • Your first sentence is incorrect. A script is run the *system* default shell, not the user's login shell, if no hashbang is present. On POSIX systems, that is `/bin/sh`. – chepner May 13 '13 at 16:57
  • @AdrianFrühwirth: Thanks again! I checked with `strace` and it starts with `execve(2)`, which recognizes `#!`. – TrueY May 13 '13 at 21:01
  • @chepner: Thanks! I tried with a script not starting with `#!` and I tried with `strace`, but it failed in `execve`. So I added a `ps -ef|grep $$` to the script and saw that the parent of `ps` and `grep` is `bash`. As `sh` is a symlink to `dash` I assume that not `/bin/sh` has been started. But linux is not 100% POSIX compliant. – TrueY May 13 '13 at 22:16
  • so `#!/bin/bash #something here` would just use `/bin/bash` as the interpreter, and disregard `#something here`? (well if I understand correctly, it would call `/bin/bash #something here`, and then `/bin/bash` would disregard the `#something here` part) – Doktor J Oct 17 '19 at 20:16
3

what is difference between 1st & 2nd shell scripts..?

No difference in output. But the time to execute both will be little different as the interpreter reads line one by one.

if i give comment(#) in 1st line after #!/bin/sh in 2nd line so what will happen ?

Any line started with (#) except the shebang(#!) is treated as a comment in shell script.

what is meaning of #!/bin/sh ?

Its the path(here - /bin/sh) to the interpreter used after the shebang (#!) . Shell will try to use the interpreter language mentioned after the shebang to execute the script.

kumarprd
  • 906
  • 2
  • 8
  • 21
  • 3
    This is not quite correct. Depending on the shell that gets executed in case of a missing shebang the output might differ based on the features of the shell in question (not for this snippet but any real case scenario). Also, they usually don't read the script line by line, they read blockwise. – Adrian Frühwirth May 14 '13 at 19:20
  • 2
    Can you comment on if the shebang line is honored in the second example? In other words, is it required that if you want a shebang it **must** be the first thing in your file? No other comments can come before it? – FGreg Jan 30 '18 at 20:12