Skip to main content
Improved formatting and punctuation; tweaked wording; updated (→https) link.
Source Link

In determining whether to use an absolute or or logical (/usr/bin/env) path to an interpreter interpreter in a she-bang shebang, there there are (2)two key considerations:

a) The interpreter can be found on targetthe target system

b) The correct version of the interpreter can can be found on targetthe target system

Since using a logical path- /usr/bin/env to the interpreter in the she-bangshebang — is the most extensible solution allowing the same script to execute successfully on target hosts with different paths to the same interpreter, we'll test it- using Python, due to its'its popularity- to determine ifwhether it meets our criteria.

  1. Does /usr/bin/env live in a predictable, consistent location on POPULAR (not "every") Operating Systems? Yes:

    Does /usr/bin/env live in a predictable, consistent location on POPULAR (not "every") operating systems? Yes:

    • RHEL 7.5
    • Ubuntu 18.04
    • Raspbian 10 ("Buster")
    • OSX 10.15.02
  2. Below Python script executed both inside and outside of virtual envelopes (Pipenv used) during tests:

    #!/usr/bin/env pythonX.x import sys print(sys.version) print('Hello, world!') 
  3. The shebang in the script was varied by the Python version number desired (all installed on the same host):

    • #!/usr/bin/env python2
    • #!/usr/bin/env python2.7
    • #!/usr/bin/env python3
    • #!/usr/bin/env python3.5
    • #!/usr/bin/env python3.6
    • #!/usr/bin/env python3.7
  4. Expected results: that print(sys.version) = env pythonX.x.  Each time ./test1.py was executed using a different installed Python version, the correct version specified in the shebang was printed.

  5. Testing Notes:

    • Tests were exclusively limited to Python
    • Perl, like Python, MUST live in /usr/bin according to the FHS
    • I've not tested every possible combination on every possible number of Linuxy/Unixy Operating System and version of each Operating System.
  • RHEL 7.5
  • Ubuntu 18.04
  • Raspbian 10 ("Buster")
  • OSX 10.15.02
  1. Below Python script executed both inside and outside of virtual envelopes (Pipenv used) during tests:
    #!/usr/bin/env pythonX.x import sys print(sys.version) print('Hello, world!') 
  2. The she-bang in the script was toggled by Python version number desired (all installed on same host):
  • #!/usr/bin/env python2
  • #!/usr/bin/env python2.7
  • #!/usr/bin/env python3
  • #!/usr/bin/env python3.5
  • #!/usr/bin/env python3.6
  • #!/usr/bin/env python3.7
  1. Expected results: that print(sys.version) = env pythonX.x. Each time ./test1.py was executed using a different installed Python version, the correct version specified in the she-bang was printed.

  2. Testing Notes:

  • Tests were exclusively limited to Python
  • Perl: Like Python- MUST live in /usr/bin according to the FHS
  • I've not tested every possible combination on every possible number of Linuxy/Unixy Operating System and version of each Operating System.

Although it's TRUE that #!/usr/bin/env python will will use the first version of Python it matches in the the user's Path, we we can enforce an express preference by specifying a version number such such as #!/usr/bin/env pythonX pythonX.xx. Indeed  Indeed, developers don't care which interpreter is found "first", all"; all they care about is that their code is executed using the specified interpreter they know to be compatible with their code to ensure to ensure consistent results- wherever that may live in the filesystem...

In terms of portability/flexibility, using a logical- /usr/bin/env - rather than absolute path not only meets requirements a), b) & c) from my testing with different versions of Python, but also has the benefit of fuzzy-logic finding the same version interpreter even if they live at different paths on different Operating Systems.     And although although MOST distros respect the FHS FHS, not all do all do.

So, where a script will FAIL if binarythe binary lives in differenta different absolute path than specified in the shebang, the the same script using a logical path SUCCEEDS as as it keeps going until it finds a match, thereby thereby offering greater reliability & extensibility across platforms.

In determining whether to use an absolute or logical (/usr/bin/env) path to an interpreter in a she-bang, there are (2) key considerations:

a) The interpreter can be found on target system

b) The correct version of interpreter can be found on target system

Since using a logical path- /usr/bin/env to the interpreter in the she-bang is the most extensible solution allowing the same script to execute successfully on target hosts with different paths to the same interpreter, we'll test it- using Python due to its' popularity- to determine if it meets our criteria.

  1. Does /usr/bin/env live in a predictable, consistent location on POPULAR (not "every") Operating Systems? Yes:
  • RHEL 7.5
  • Ubuntu 18.04
  • Raspbian 10 ("Buster")
  • OSX 10.15.02
  1. Below Python script executed both inside and outside of virtual envelopes (Pipenv used) during tests:
    #!/usr/bin/env pythonX.x import sys print(sys.version) print('Hello, world!') 
  2. The she-bang in the script was toggled by Python version number desired (all installed on same host):
  • #!/usr/bin/env python2
  • #!/usr/bin/env python2.7
  • #!/usr/bin/env python3
  • #!/usr/bin/env python3.5
  • #!/usr/bin/env python3.6
  • #!/usr/bin/env python3.7
  1. Expected results: that print(sys.version) = env pythonX.x. Each time ./test1.py was executed using a different installed Python version, the correct version specified in the she-bang was printed.

  2. Testing Notes:

  • Tests were exclusively limited to Python
  • Perl: Like Python- MUST live in /usr/bin according to the FHS
  • I've not tested every possible combination on every possible number of Linuxy/Unixy Operating System and version of each Operating System.

Although it's TRUE that #!/usr/bin/env python will use the first version of Python it matches in the user's Path, we can enforce an express preference by specifying a version number such as #!/usr/bin/env pythonX.x. Indeed, developers don't care which interpreter is found "first", all they care about is that their code is executed using the specified interpreter they know to be compatible with their code to ensure consistent results- wherever that may live in the filesystem...

In terms of portability/flexibility, using a logical- /usr/bin/env - rather than absolute path not only meets requirements a), b) & c) from my testing with different versions of Python, but also has the benefit of fuzzy-logic finding the same version interpreter even if they live at different paths on different Operating Systems.  And although MOST distros respect the FHS, not all do.

So where a script will FAIL if binary lives in different absolute path than specified in shebang, the same script using a logical path SUCCEEDS as it keeps going until it finds a match, thereby offering greater reliability & extensibility across platforms.

In determining whether to use an absolute or logical (/usr/bin/env) path to an interpreter in a shebang, there are two key considerations:

a) The interpreter can be found on the target system

b) The correct version of the interpreter can be found on the target system

Since using a logical path /usr/bin/env to the interpreter in the shebang — is the most extensible solution allowing the same script to execute successfully on target hosts with different paths to the same interpreter, we'll test it using Python, due to its popularity to determine whether it meets our criteria.

  1. Does /usr/bin/env live in a predictable, consistent location on POPULAR (not "every") operating systems? Yes:

    • RHEL 7.5
    • Ubuntu 18.04
    • Raspbian 10 ("Buster")
    • OSX 10.15.02
  2. Below Python script executed both inside and outside of virtual envelopes (Pipenv used) during tests:

    #!/usr/bin/env pythonX.x import sys print(sys.version) print('Hello, world!') 
  3. The shebang in the script was varied by the Python version number desired (all installed on the same host):

    • #!/usr/bin/env python2
    • #!/usr/bin/env python2.7
    • #!/usr/bin/env python3
    • #!/usr/bin/env python3.5
    • #!/usr/bin/env python3.6
    • #!/usr/bin/env python3.7
  4. Expected results: that print(sys.version) = env pythonX.x.  Each time ./test1.py was executed using a different installed Python version, the correct version specified in the shebang was printed.

  5. Testing Notes:

    • Tests were exclusively limited to Python
    • Perl, like Python, MUST live in /usr/bin according to the FHS
    • I've not tested every possible combination on every possible number of Linuxy/Unixy Operating System and version of each Operating System.

Although it's TRUE that #!/usr/bin/env python will use the first version of Python it matches in the user's Path, we can enforce an express preference by specifying a version number such as #!/usr/bin/env pythonX.x.  Indeed, developers don't care which interpreter is found "first"; all they care about is that their code is executed using the specified interpreter they know to be compatible with their code to ensure consistent resultswherever that may live in the filesystem...

In terms of portability/flexibility, using a logical /usr/bin/env rather than absolute path not only meets requirements a), b) & c) from my testing with different versions of Python, but also has the benefit of fuzzy-logic finding the same version interpreter even if they live at different paths on different Operating Systems.   And although MOST distros respect the FHS, not all do.

So, where a script will FAIL if the binary lives in a different absolute path than specified in the shebang, the same script using a logical path SUCCEEDS as it keeps going until it finds a match, thereby offering greater reliability & extensibility across platforms.

Corrected my use of colloquial language
Source Link
F1Linux
  • 2.8k
  • 2
  • 23
  • 34

Since using a logical path- /usr/bin/env to the interpreter in the she-bang is the most extensible solution allowing the same script to execute successfully on target hosts with different paths to the same interpreter, we'll test it- using Python due to its' popularity- to seedetermine if it meets our criteria.

  • Tests were exclusively limited to Python
  • Perl: Like Python- MUST live in /usr/bin according to the FHS
  • I've not triedtested every possible combination on every possible number of Linuxy/Unixy Operating System and version of each Operating System.

Although it's TRUE that #!/usr/bin/env python will use the first version of Python it findsmatches in the user's Path, we can moderate this behaviourenforce an express preference by specifying a version number such as #!/usr/bin/env pythonX.x. Indeed, developers don't care which interpreter is found "first", all they care about is that their code is executed using the specified interpreter they know to be compatible with their code to ensure consistent results- wherever that may live in the filesystem...

Since using a logical path- /usr/bin/env to the interpreter in the she-bang is the most extensible solution allowing the same script to execute successfully on target hosts with different paths to the same interpreter, we'll test it- using Python due to its' popularity- to see if it meets our criteria.

  • Tests were exclusively limited to Python
  • Perl: Like Python- MUST live in /usr/bin according to the FHS
  • I've not tried every possible combination on every possible number of Linuxy/Unixy Operating System and version of each Operating System.

Although it's TRUE that #!/usr/bin/env python will use the first version of Python it finds in the user's Path, we can moderate this behaviour by specifying a version number such as #!/usr/bin/env pythonX.x. Indeed, developers don't care which interpreter is found "first", all they care about is that their code is executed using the specified interpreter they know to be compatible with their code to ensure consistent results- wherever that may live in the filesystem...

Since using a logical path- /usr/bin/env to the interpreter in the she-bang is the most extensible solution allowing the same script to execute successfully on target hosts with different paths to the same interpreter, we'll test it- using Python due to its' popularity- to determine if it meets our criteria.

  • Tests were exclusively limited to Python
  • Perl: Like Python- MUST live in /usr/bin according to the FHS
  • I've not tested every possible combination on every possible number of Linuxy/Unixy Operating System and version of each Operating System.

Although it's TRUE that #!/usr/bin/env python will use the first version of Python it matches in the user's Path, we can enforce an express preference by specifying a version number such as #!/usr/bin/env pythonX.x. Indeed, developers don't care which interpreter is found "first", all they care about is that their code is executed using the specified interpreter they know to be compatible with their code to ensure consistent results- wherever that may live in the filesystem...

  • #!/usr/bin/env python2#!/usr/bin/env python2
  • #!/usr/bin/env python2.7#!/usr/bin/env python2.7
  • #!/usr/bin/env python3#!/usr/bin/env python3
  • #!/usr/bin/env python3.5#!/usr/bin/env python3.5
  • #!/usr/bin/env python3.6#!/usr/bin/env python3.6
  • #!/usr/bin/env python3.7#!/usr/bin/env python3.7

So where a script will FAIL if binary lives in different absolute path thenthan specified in shebang, the same script using a logical path SUCCEEDS as it keeps going until it finds a match, thereby offering greater reliability & extensibility across platforms.

  • #!/usr/bin/env python2
  • #!/usr/bin/env python2.7
  • #!/usr/bin/env python3
  • #!/usr/bin/env python3.5
  • #!/usr/bin/env python3.6
  • #!/usr/bin/env python3.7

So where a script will FAIL if binary lives in different absolute path then specified in shebang, the same script using a logical path SUCCEEDS as it keeps going until it finds a match, thereby offering greater reliability & extensibility across platforms.

  • #!/usr/bin/env python2
  • #!/usr/bin/env python2.7
  • #!/usr/bin/env python3
  • #!/usr/bin/env python3.5
  • #!/usr/bin/env python3.6
  • #!/usr/bin/env python3.7

So where a script will FAIL if binary lives in different absolute path than specified in shebang, the same script using a logical path SUCCEEDS as it keeps going until it finds a match, thereby offering greater reliability & extensibility across platforms.

Minor reformatting: use block code tag adapted for list use instead of wrapped inline code
Source Link
AdminBee
  • 23.6k
  • 25
  • 55
  • 77
Loading
Updated my Answer's "Testing" & Conclusion" sections to address @KeithThompson 's concerns raised in comment, which were deserved expanded coverage
Source Link
F1Linux
  • 2.8k
  • 2
  • 23
  • 34
Loading
Source Link
F1Linux
  • 2.8k
  • 2
  • 23
  • 34
Loading