Explanation for newbies:
-
Shell is the programming language that you use when you open a terminal on linux or mac os. Well, actually “shell” is a family of languages with many different implementations (bash, dash, ash, zsh, ksh, fish, …)
-
Writing programs in shell (called “shell scripts”) is a harrowing experience because the language is optimized for interactive use at a terminal, not writing extensive applications
-
The two lines in the meme change the shell’s behavior to be slightly less headache-inducing for the programmer:
set -euo pipefailis the short form of the following three commands:set -e: exit on the first command that fails, rather than plowing through ignoring all errorsset -u: treat references to undefined variables as errorsset -o pipefail: If a command piped into another command fails, treat that as an error
export LC_ALL=Ctells other programs to not do weird things depending on locale. For example, it forcesseqto output numbers with a period as the decimal separator, even on systems where coma is the default decimal separator (russian, dutch, etc.).
-
The title text references “posix”, which is a document that standardizes, among other things, what features a shell must have. Posix does not require a shell to implement
pipefail, so if you want your script to run on as many different platforms as possible, then you cannot use that feature.


just use python instead.
subprocess.run(), to call to system utilspathlib.Pathfor file paths and reading/writing to filesshutil.which()to resolve utilities from yourPathenv varHere’s an example of some python i use to launch vscode (and terminals, but that requires
dbus)from pathlib import Path from shutil import which from subprocess import run def _run(cmds: list[str], cwd=None): p = run(cmds, cwd=cwd) # raises an error if return code is non-zero p.check_returncode() return p VSCODE = which('code') SUDO = which('sudo') DOCKER = which('docker') proj_dir = Path('/path/to/repo') docker_compose = proj_dir / 'docker/' windows = [ proj_dir / 'code', proj_dir / 'more_code', proj_dir / 'even_more_code/subfolder', ] for w in windows: _run([VSCODE, w]) _run([SUDO, DOCKER, 'compose', 'up', '-d'], cwd=docker_compose)deleted by creator
that is a little more complicated
p.communicate()will take a string (or bytes) and send it to the stdin of the process, then wait forpto finish executionthere are ways to stream input into a running process (without waiting for the process to finish), but I don’t remember how off the top of my head
from shutil import which from subprocess import Popen, PIPE, run from pathlib import Path LS = which('ls') REV = which('rev') ls = run([LS, Path.home()], stdout=PIPE) p = Popen([REV], stdin=PIPE, stdout=PIPE) stdout, stderr = p.communicate(ls.stdout) print(stdout.decode('utf-8'))Or Rust. Use Command::new() for system commands and Path::new() for paths.