3

If I have included a configuration file (variables defines in shell script) or library file (has common function definitions) in my main script (which has shebang), then do I need a shebang for that configuration shell script also ?

Edit: I am including the configuration file using . or source Main file contains #!/bin/sh shebang.

Patrick
  • 2,464
  • 3
  • 30
  • 47

2 Answers2

7

Depends how you are calling it. Using source or . commands then no, if calling them as a child process using just the script name, then yes.

From your description then you are "sourcing" the files, so no, #! will just be a comment. It may also be prudent to remove execute access from these files so they are not inadvertently called as child processes.

(If they are not "sourced" then the definitions would only happen in the child process and would be useless)

EDIT following @triplee comment:

They could be invoked as a child process using (for example) sh filename, bash filename, or even (shudder) csh filename. All of these shells have differences, so one advantage of a #! line is as a comment indicating which shell type the code is written for. I wouldn't use it for that though, because it also implies it can be run as a child. I'm sure you comment your code sufficiently already, but it might be worth adding comments to indicate the shell.

cdarke
  • 42,728
  • 8
  • 80
  • 84
  • 2
    Also, if you always explicitly invoke the script with `sh script` or `bash script` then the shebang is obviously ignored. Maybe also point out that the two are different; `sh` has different behavior, even when it's a symlink to `bash`. – tripleee May 11 '16 at 07:11
  • @tripleee how does it have different behaviour when symlinked ? – 123 May 11 '16 at 07:12
  • using a symbolic-link should make no difference, that is a feature of the filesystem, not the shell. How is a symbolic link relevant here? – cdarke May 11 '16 at 07:18
  • Bash notices when it is invoked as `sh` and switches to POSIX mode. This is a common FAQ. – tripleee May 11 '16 at 07:21
  • 1
    @123 now I see what you mean `sh -> bash`. This is very common device on UNIX systems (`ls -l /bin`) where we have one program having a superset of features of another. It reduces the amount of code maintanence. On Linux, for example, it is also common to see `awk -> gawk`. It also allows backward compatibility, hardly anyone uses the original `awk` code, `nawk` or `gawk` is generally used, but to drop `awk` would break thousands of scripts. `gawk` in particular has many useful extensions not available when called `awk`. – cdarke May 11 '16 at 08:10
  • 1
    @cdarke Realised that immediately after asking, left the comment there for confirmation though, so thanks for the reply. In regards to awk though, gawk does not perfectly emulate posix awk even when you use compat or posix. Unfortunately i (as I'm sure you'll ask) i cannot remember exactly what the problem was, but i remember it accepting something in gawk compat that would not work in regular awk. – 123 May 11 '16 at 08:22
  • 1
    Well, you have the same problem with Bash as `sh`. It provides a number of non-POSIX features even when nominally in POSIX mode. – tripleee May 11 '16 at 11:54
  • and there is the point of why bother with POSIX if everyone is using `bash`? Not good enough to say that `bash` has different versions, because so does POSIX. Korn shell 93 broke several things (especially functions) when it moved from ksh 88 in the name of POSIX, but that didn't help it. People use `bash` because its there. As @triplee says, it is very common here that people don't appreciate the difference between `sh` and `bash`, and so many people still use ancient structures like `[` and `-lt`, `-eq`, even though their replacements have been in POSIX for ages. – cdarke May 11 '16 at 15:53
  • Not everyone is using Bash. Solaris and some *BSDs are prime examples. Many scripts need to work portably on big-iron dinosaurs running HP-UX or whatever. But this question is tagged [tag:bash] so this discussion should probably end here. – tripleee May 11 '16 at 16:38
0

#! with an interpreter, say bash, should not be used :

  1. When you wish to use the existing environment variables without exporting it.
  2. When you wish to include a configuration file to the parent script(Use source or . instead)

The shebang makes the interpreter execute the script which contained the shebang itself(a bootstrap mechanism) and during this execution, the line with shebang is just considered as a comment.

Since a new shell (child) is spawned in this case, the old environment is forgotten and the variables which were not exported will be forgotten in the new shell.

sjsam
  • 21,411
  • 5
  • 55
  • 102