On Thu, Oct 3, 2019 at 11:41 PM Hongyi Zhao <hongyi.z...@gmail.com> wrote: > > On Thu, 03 Oct 2019 23:12:45 +1000, Chris Angelico wrote: > > > > Seems fine. Most of the code is elsewhere, and presumably has been > > written to support both Py2 and Py3; the file you're linking to is > > *just* a wrapper that finds an interpreter to use. > > > > Though this should be unnecessary. A simple shebang of "/usr/bin/env > > python3" will suffice for many many situations (and then if someone > > specifically wants to run it in a legacy interpreter, an explicit > > "python2 scriptname.py" or "python scriptname.py" will work). > > I'm very confusing on the following part in this script: > > ---- > ''':' # begin python string; this line is interpreted by the shell as `:` > which python >/dev/null 2>&1 && exec python "$0" "$@" > which python3 >/dev/null 2>&1 && exec python3 "$0" "$@" > which python2 >/dev/null 2>&1 && exec python2 "$0" "$@" > >&2 echo "error: cannot find python" > exit 1 > ''' > ---- > > Any hints for the meaning of several ' used above? >
The hint is there in that line, and stems from the way two different parsers (Python and sh) interpret the line. In Python, three single quote characters start a triple-quoted string, which doesn't end till you get three more; since nothing is done with this string, Python parses it and then ignores it. In the shell, the first two are an empty string, then ':' is a colon, which introduces a label (the fact that it's in quotes is irrelevant to the shell). So there's an empty label followed by a shell comment. The shell parses this line and does nothing with it. Then it moves on to the next lines, and runs the shell script. Since this shell script ends with 'exit 1', it's guaranteed to halt execution (and usually it'll exec to python, which also halts execution), so the Python code won't be executed. This is a common trick when writing polyglot code. You make the relevant code for one language appear as a comment or string literal in another. For instance, you can open a C program with "#if 0", which will cause the following text to be ignored by the C preprocessor; but since that line begins with a hash, Python will ignore it (but continue executing). ChrisA -- https://mail.python.org/mailman/listinfo/python-list