Consider this command in bash:
docker run -d \
--rm \
--name postgres-prod \
--env TZ="Europe/Budapest" \
--mount type=bind,src=/secure/postgres/prod/data,dst=/var/lib/postgresql/data \
--mount type=bind,src=/secure/postgres/prod/backup,dst=/backup \
--mount type=bind,src=/secure/postgres/secrets/postgres_pwd.txt,dst=/etc/postgres_pwd.txt \
--env POSTGRES_PASSWORD_FILE="/etc/postgres_pwd.txt" \
-p 0.0.0.0:5432:5432 \
postgres_hun:11
I want to split very long commands like the above in xonsh scripts. If I simply use the above script with xonsh then I get this error:
./test.xsh
/usr/lib/python3/dist-packages/apport/report.py:13: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import fnmatch, glob, traceback, errno, sys, atexit, locale, imp, stat
Traceback (most recent call last):
File "/usr/bin/xonsh", line 4, in <module>
main()
File "/usr/lib/python3/dist-packages/xonsh/__amalgam__.py", line 24019, in main
_failback_to_other_shells(args, err)
File "/usr/lib/python3/dist-packages/xonsh/__amalgam__.py", line 23983, in _failback_to_other_shells
raise err
File "/usr/lib/python3/dist-packages/xonsh/__amalgam__.py", line 24017, in main
return main_xonsh(args)
File "/usr/lib/python3/dist-packages/xonsh/__amalgam__.py", line 24060, in main_xonsh
run_script_with_cache(
File "/usr/lib/python3/dist-packages/xonsh/__amalgam__.py", line 3041, in run_script_with_cache
ccode = compile_code(filename, code, execer, glb, loc, mode)
File "/usr/lib/python3/dist-packages/xonsh/__amalgam__.py", line 3000, in compile_code
ccode = execer.compile(code, glbs=glb, locs=loc, mode=mode, filename=filename)
File "/usr/lib/python3/dist-packages/xonsh/__amalgam__.py", line 23105, in compile
code = compile(tree, filename, mode)
TypeError: expected Module node, got Expression
I'm not sure what the problem is. Backslash can also be used for line continuation in python, I think this should work but it doesn't. Also tried to put the whole thing between parentheses, and also put it inside $() but those don't work either.
I came up with this "solution":
#!/usr/bin/xonsh
import subprocess
cmd = [
"docker", "run", "-d", "--rm",
"--name", "postgres-prod",
"--env", 'TZ="Europe/Budapest',
"--mount", "type=bind,src=/secure/postgres/prod/data,dst=/var/lib/postgresql/data",
"--mount", "type=bind,src=/secure/postgres/prod/backup,dst=/backup",
"--mount", "type=bind,src=/secure/postgres/secrets/postgres_pwd.txt,dst=/etc/postgres_pwd.txt",
"--env", "POSTGRES_PASSWORD_FILE=/etc/postgres_pwd.txt",
"-p", "0.0.0.0:5432:5432",
"postgres_hun:11"
]
subprocess.run(cmd, shell=False)
But this looks ugly, hard to read, easy to mistype, clumsy etc.
I have read the xonsh tutorial, also the "bash to xonsh transition" part but there was nothing about splitting long commands into multiple lines.
How can I do this without adding too much syntax noise? Something that is easy to write and read, and easy to use?