Destination #! / Bin / false in bash script

While working on a project written by my former colleague in bash, I noticed that all .sh files contain nothing but function definitions, starting with #!/bin/false , which, as I understand it, is a security mechanism preventing the execution of include -only.

Example:

my_foo.sh

 #!/bin/false function foo(){ echo foontastic } 

my_script.sh

 #!/bin/bash ./my_foo.sh # does nothing foo # error, no command named "foo" . ./my_foo.sh foo # prints "foontastic" 

However, when I do not use #!/bin/false , the effects of both correct and incorrect use are exactly the same:

Example:

my_bar.sh

 function bar(){ echo barvelous } 

my_script.sh

  #!/bin/bash ./my_bar.sh # spawn a subshell, defines bar and exit, effectively doing nothing bar # error, no command named "bar" . ./my_bar.sh bar # prints "barvelous" 

Since the correct use of these scripts by including them with source in both cases works as expected, and their execution in both cases does not do anything from the point of view of the parent shell and does not generate an error message regarding the invalid use, what exactly is Goal #!/bash/false in these script?

+5
source share
2 answers

In general, consider a testcode file with bash code in it

 #!/bin/bash if [ "$0" = "${BASH_SOURCE[0]}" ]; then echo "You are executing ${BASH_SOURCE[0]}" else echo "You are sourcing ${BASH_SOURCE[0]}" fi 

you can do three different things with it:

 $ ./testcode You are executing ./testcode 

This works if the test code has the correct permissions and the correct shebang. With the help of shebang #!/bin/false this does not output anything and returns code 1 (false).

 $ bash ./testcode You are executing ./testcode 

This completely ignores the shebang (which may even be absent), and it only needs read permission, not permission to execute. This is a way to invoke bash scripts from the CMD command prompt on Windows (if you have bash.exe in PATH ...), since shebang machanism does not work there.

 $ . ./testcode You are sourcing ./testcode 

This also completely ignores shebang, as mentioned above, but this is a completely different matter, because finding a script means that the current shell is executing it, and executing a script means calling a new shell to execute it. For example, if you put the exit in the source code of the script, you will exit the current shell, which you rarely need. Therefore, the search is often used to load definitions of functions or constants, which is somewhat reminiscent of the import statement of other programming languages, and different programmers develop different habits to distinguish between scripts to be executed and include files to be received. Usually I do not use the extension for the former (others use .sh ), but I use the extension .shinc for the latter. Your former colleague used shebang #!/bin/false , and you can only ask them why they chose this over two million other options. One of the reasons, in my opinion, is that you can use file to split these files:

 $ file testcode testcode2 testcode: Bourne-Again shell script, ASCII text executable testcode2: a /bin/false script, ASCII text executable 

Of course, if they include files containing only function definitions, they are harmless to execute them, so I don’t think your colleague did this to prevent execution.

My other Python-inspired habit is to put some regression tests at the end of my .shinc files (at least during development)

 ... function definitions here ... [ "$0" != "${BASH_SOURCE[0]}" ] && return ... regression tests here ... 

Since return generates an error in executable scripts, but in script order, a more cryptic way to get the same result:

 ... function definitions here ... return 2>/dev/null || : ... regression tests here ... 
+4
source

The difference in using #!/bin/false or not in terms of the parent shell is in the return code.

/bin/false always returns a return code with an error (in my case 1, but not sure if it is standard).

Try the following:

 ./my_foo.sh //does nothing echo $? // shows "1", aka failing ./my_bar.sh //does nothing echo $? // shows "0", aka everything went right 

Thus, the use of #!/bin/false not only documents the fact that the script is not intended to be executed, but also generates an error return code.

+1
source

Source: https://habr.com/ru/post/1263316/


All Articles