Should I put #! (shebang) in Python scripts, and what form should it take?

前端 未结 12 1042
感动是毒
感动是毒 2020-11-22 01:27

Should I put the shebang in my Python scripts? In what form?

#!/usr/bin/env python 

or



        
相关标签:
12条回答
  • 2020-11-22 01:55

    Sometimes, if the answer is not very clear (I mean you cannot decide if yes or no), then it does not matter too much, and you can ignore the problem until the answer is clear.

    The #! only purpose is for launching the script. Django loads the sources on its own and uses them. It never needs to decide what interpreter should be used. This way, the #! actually makes no sense here.

    Generally, if it is a module and cannot be used as a script, there is no need for using the #!. On the other hand, a module source often contains if __name__ == '__main__': ... with at least some trivial testing of the functionality. Then the #! makes sense again.

    One good reason for using #! is when you use both Python 2 and Python 3 scripts -- they must be interpreted by different versions of Python. This way, you have to remember what python must be used when launching the script manually (without the #! inside). If you have a mixture of such scripts, it is a good idea to use the #! inside, make them executable, and launch them as executables (chmod ...).

    When using MS-Windows, the #! had no sense -- until recently. Python 3.3 introduces a Windows Python Launcher (py.exe and pyw.exe) that reads the #! line, detects the installed versions of Python, and uses the correct or explicitly wanted version of Python. As the extension can be associated with a program, you can get similar behaviour in Windows as with execute flag in Unix-based systems.

    0 讨论(0)
  • 2020-11-22 01:57

    It's really just a matter of taste. Adding the shebang means people can invoke the script directly if they want (assuming it's marked as executable); omitting it just means python has to be invoked manually.

    The end result of running the program isn't affected either way; it's just options of the means.

    0 讨论(0)
  • 2020-11-22 01:57

    If you have different modules installed and need to use a specific python install, then shebang appears to be limited at first. However, you can do tricks like the below to allow the shebang to be invoked first as a shell script and then choose python. This is very flexible imo:

    #!/bin/sh
    #
    # Choose the python we need. Explanation:
    # a) '''\' translates to \ in shell, and starts a python multi-line string
    # b) "" strings are treated as string concat by python, shell ignores them
    # c) "true" command ignores its arguments
    # c) exit before the ending ''' so the shell reads no further
    # d) reset set docstrings to ignore the multiline comment code
    #
    "true" '''\'
    PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
    ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
    FALLBACK_PYTHON=python3
    
    if [ -x $PREFERRED_PYTHON ]; then
        echo Using preferred python $PREFERRED_PYTHON
        exec $PREFERRED_PYTHON "$0" "$@"
    elif [ -x $ALTERNATIVE_PYTHON ]; then
        echo Using alternative python $ALTERNATIVE_PYTHON
        exec $ALTERNATIVE_PYTHON "$0" "$@"
    else
        echo Using fallback python $FALLBACK_PYTHON
        exec python3 "$0" "$@"
    fi
    exit 127
    '''
    
    __doc__ = """What this file does"""
    print(__doc__)
    import platform
    print(platform.python_version())
    

    Or better yet, perhaps, to facilitate code reuse across multiple python scripts:

    #!/bin/bash
    "true" '''\'; source $(cd $(dirname ${BASH_SOURCE[@]}) &>/dev/null && pwd)/select.sh; exec $CHOSEN_PYTHON "$0" "$@"; exit 127; '''
    

    and then select.sh has:

    PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
    ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
    FALLBACK_PYTHON=python3
    
    if [ -x $PREFERRED_PYTHON ]; then
        CHOSEN_PYTHON=$PREFERRED_PYTHON
    elif [ -x $ALTERNATIVE_PYTHON ]; then
        CHOSEN_PYTHON=$ALTERNATIVE_PYTHON
    else
        CHOSEN_PYTHON=$FALLBACK_PYTHON
    fi
    
    0 讨论(0)
  • 2020-11-22 01:59

    If you have more than one version of Python and the script needs to run under a specific version, the she-bang can ensure the right one is used when the script is executed directly, for example:

    #!/usr/bin/python2.7
    

    Note the script could still be run via a complete Python command line, or via import, in which case the she-bang is ignored. But for scripts run directly, this is a decent reason to use the she-bang.

    #!/usr/bin/env python is generally the better approach, but this helps with special cases.

    Usually it would be better to establish a Python virtual environment, in which case the generic #!/usr/bin/env python would identify the correct instance of Python for the virtualenv.

    0 讨论(0)
  • 2020-11-22 01:59

    When I installed Python 3.6.1 on Windows 7 recently, it also installed the Python Launcher for Windows, which is supposed to handle the shebang line. However, I found that the Python Launcher did not do this: the shebang line was ignored and Python 2.7.13 was always used (unless I executed the script using py -3).

    To fix this, I had to edit the Windows registry key HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.File\shell\open\command. This still had the value

    "C:\Python27\python.exe" "%1" %*
    

    from my earlier Python 2.7 installation. I modified this registry key value to

    "C:\Windows\py.exe" "%1" %*
    

    and the Python Launcher shebang line processing worked as described above.

    0 讨论(0)
  • 2020-11-22 02:02

    Should I put the shebang in my Python scripts?

    Put a shebang into a Python script to indicate:

    • this module can be run as a script
    • whether it can be run only on python2, python3 or is it Python 2/3 compatible
    • on POSIX, it is necessary if you want to run the script directly without invoking python executable explicitly

    Are these equally portable? Which form is used most?

    If you write a shebang manually then always use #!/usr/bin/env python unless you have a specific reason not to use it. This form is understood even on Windows (Python launcher).

    Note: installed scripts should use a specific python executable e.g., /usr/bin/python or /home/me/.virtualenvs/project/bin/python. It is bad if some tool breaks if you activate a virtualenv in your shell. Luckily, the correct shebang is created automatically in most cases by setuptools or your distribution package tools (on Windows, setuptools can generate wrapper .exe scripts automatically).

    In other words, if the script is in a source checkout then you will probably see #!/usr/bin/env python. If it is installed then the shebang is a path to a specific python executable such as #!/usr/local/bin/python (NOTE: you should not write the paths from the latter category manually).

    To choose whether you should use python, python2, or python3 in the shebang, see PEP 394 - The "python" Command on Unix-Like Systems:

    • ... python should be used in the shebang line only for scripts that are source compatible with both Python 2 and 3.

    • in preparation for an eventual change in the default version of Python, Python 2 only scripts should either be updated to be source compatible with Python 3 or else to use python2 in the shebang line.

    0 讨论(0)
提交回复
热议问题