"""Check that executable text files have a shebang.""" import argparse import shlex import sys from typing import Optional from typing import Sequence def check_has_shebang(path: str) -> int: with open(path, 'rb') as f: first_bytes = f.read(2) if first_bytes != b'#!': quoted = shlex.quote(path) print( f'{path}: marked executable but has no (or invalid) shebang!\n' f" If it isn't supposed to be executable, try: " f'`chmod -x {quoted}`\n' f' If it is supposed to be executable, double-check its shebang.', file=sys.stderr, ) return 1 else: return 0 def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('filenames', nargs='*') args = parser.parse_args(argv) retv = 0 for filename in args.filenames: retv |= check_has_shebang(filename) return retv if __name__ == '__main__': exit(main())