Python: Read the shebang line of a script

Rate this post
#!/usr/bin/env python
# Author: James Cherti
# License: MIT
# URL: https://www.jamescherti.com/python-read-the-shebang-line-of-a-script/
"""Read the shebang line of a script."""

import sys
import os
import shlex
from pathlib import Path
from typing import Union


class ShebangError(Exception):
    """Error with the method read_shebang()."""


def read_shebang(script_path: Union[Path, str]) -> list:
    """Return the shebang line of a file.

    >>> shebang("file.sh")
    ['/usr/bin/env', 'bash']

    """
    with open(script_path, "rb") as fhandler:
        line = fhandler.readline().strip().decode()

    if len(line) > 2 and line[0:2] == '#!':
        shebang_split = shlex.split(line[2:].strip())
        if not Path(shebang_split[0]).is_file():
            raise ShebangError(f"the shebang '{shebang_split}' does not exist")

        if not os.access(shebang_split[0], os.X_OK):
            raise ShebangError(f"the shebang '{shebang_split}' is not "
                               "executable")

        return shebang_split

    raise ShebangError("the shebang line was not found")

    
if __name__ == "__main__":
    try:
        print(read_shebang(sys.argv[1]))
    except IndexError:
        print(f"Usage: {sys.argv[0]} <file>", file=sys.stderr)
        sys.exit(1)Code language: Python (python)