The curious case of shell commands, or how "this bug is required by POSIX" (2021)

Overall reaction to the article

  • Some see it as “woefully misguided” because invoking a shell is often an intentional feature, not a bug (e.g., popen("gzip > foo.gz")).
  • Others argue it’s mostly correct about real problems, even if the tone is dramatic and some examples (like Shellshock) are misclassified.
  • General agreement that the writing is meandering; the useful part is the concrete experiments and examples.

system(), exec, and when shells are appropriate

  • Broad agreement: avoid system() in new code when you just want to run a specific program; use exec*()/posix_spawn() or language-level process APIs (e.g., Python subprocess.run([...])).
  • Counterpoint: system() exists because people do want shell features (pipelines, redirection, small utilities); removing it will just make people reimplement it badly.
  • One view: “If you’re sanitizing, you’re losing” — better to avoid mixing code and data than rely on ad‑hoc sanitization.

SSH and remote command execution

  • ssh host "cmd args" joins arguments with spaces and runs them via the user’s login shell, not necessarily POSIX sh, which breaks quoting assumptions and is considered a serious design wart.
  • Debate whether this behavior is “hidden” or adequately documented in man ssh; consensus that it’s at least surprising and adds no real functionality, only risk.
  • Some tools/workarounds: pseudoshells that transport argv intact, shlex.join() in Python, custom quoting helpers.

Quoting and escaping techniques

  • Many examples of correct quoting:
    • Bash: printf '%q', ${var@Q}, printf -v.
    • Python: shlex.quote, shlex.join, subprocess.Popen pipelines.
    • Shell helper patterns like quote-argv() { printf '%q ' "$@"; } and -- to stop option parsing.
  • Discussion of tricky edge cases: arguments starting with -, spaces, quotes, nested shells, and SSH layers.

Shell design, alternatives, and platforms

  • Critique that traditional shells make safe string handling hard; proposals:
    • New shells (e.g., YSH/Oil) with safer word evaluation, structured data (JSON/JSON8), and better eval semantics.
    • More explicit “invoke external only” builtins instead of relying on implicit sh -c.
  • POSIX vs Windows:
    • POSIX has argv-based APIs and a well-known shell model, but still fragile.
    • Windows fundamentally uses a single command-line string and program-specific parsing, making generic safe wrappers harder; referenced Rust CVE and Java behavior.