Some notes on providing Python code as a command line argument
I've long known about CPython's '
-c' argument, which (in the words
of the manual page) lets you "specify the command [for CPython] to
execute". Until recently, I thought it had to be a single statement,
or at least a single line of Python code (which precluded a number
of things). It turns out that this isn't the case; both CPython and
PyPy will accept a command line argument for -c that contains
embedded newlines, in the style of providing command line code to
Unix tools like awk.
python -c 'import sys if len(sys.argv) > 1: print("arguments:", sys.argv[1:]) else: print("no arguments")' "$@"
(For various reasons, you still might want to make this code importable, although I haven't done so here.)
If you're directly supplying the code on the command line, as I am here, you have a choice (in a Bourne shell script or environment). You can quote the entire code with single quotes and not use a literal single quote in the Python code, or you can quote with double quotes and carefully escape several special characters but get to use single quotes. If you want to avoid all of this, you need to put the code into a shell variable:
pyprog="$(cat <<'EOF' [....] EOF )" python -c "$pyprog" ...
As you'd expect, '
__name__' in the command line code is the
__main__'. As the manual page covers, all further command
line arguments as passed in sys.argv, with sys.argv set to '-c'.
Since the code doesn't have a file name (which is what would normally
go in sys.argv), this seems like a decent choice, and immediately
passing further arguments to the code is convenient.
Although this makes it possible to have a Python program embedded into a shell script in the same way that you can do this with awk (and thus implicitly helps enable Python as a filter in a shell script), I personally don't find the idea too appealing, at least for Python code of any substance. The problem isn't the need to take extra care with embedding the Python code in your shell script, although that's not great. The real problem is that embedding Python code this way means you miss out on all sorts of tools that are in the Python programming ecology, because they only work on separate Python code.
(If I had to write something this way, I would be tempted to develop it in a separate file that the shell script invoked with 'python <filename>' instead of 'python -c', and then only embed the code into the shell script and switch to 'python -c ...' at the last moment.)
PS: Now that I know how to do this it's a little bit tempting to
try out small amounts of Python code in places where awk doesn't
quite have the functions and power I'd like (or at least doesn't
make the functions as easy as Python does). On the other hand, awk
doesn't make you think about character set conversion issues.
Probably I wouldn't use this to parse and reformat
JSON, though. That's likely to
be enough code that I'd want to use the usual Python tools on it.
Comments on this page:Written on 24 May 2022.