Katkat

Explain and Harden Two Shell Commands

ModalSoftware Engineer · Technical Screen

Last updated

Tests deep understanding of Unix shell semantics, process management, file permissions, and standard stream handling by diagnosing subtle failure modes in common shell one-liners and writing robust, production-grade replacements.

Scenario

During an infrastructure review, you discover the following two shell snippets used in automated cleanup and background worker management scripts:

Snippet A

ps aux | grep my_worker | awk '{print $2}' | xargs kill -9

Snippet B

chmod -R 777 $DEPLOY_DIR && ./bin/migrate --env=$ENV 2>&1 > /dev/null &

Both commands are prone to edge cases, race conditions, security issues, and silent failures in production environments.

Tasks

1. Analysis and Pitfalls

For each snippet:

  • Explain step-by-step how the pipeline or sequence executes.
  • Identify at least three distinct pitfalls, safety risks, or edge cases. Consider topics such as substring matching, process table races, argument expansion/quoting, file permissions, stream redirection order, and silent failure modes.

2. Hardened Implementation

Provide a hardened, idiomatic shell snippet to replace each command.

For Snippet A, your replacement should:

  • Target only the intended processes without matching the search command itself or unrelated processes containing my_worker as a substring (e.g., my_worker_supervisor.py).
  • Handle the case where zero matching processes exist without producing errors.
  • Allow processes a graceful shutdown window before forcing termination.

For Snippet B, your replacement should:

  • Avoid overly permissive global permissions, adhering to the principle of least privilege.
  • Safely handle paths with spaces or special characters.
  • Correctly redirect streams so stdout and stderr are preserved into a dedicated log file rather than discarded.
  • Ensure the background job status or PID is trackable and failures in directory permission updates prevent the migration from running.

Hints

Hint 1

Look closely at the command line that `ps aux` prints; does `grep` appear in that list, and what happens if another command contains `my_worker` in its parameters?

Hint 2

Consider stream redirection order in bash: `2>&1 > /dev/null` binds descriptor 2 to the current target of descriptor 1 before descriptor 1 is redirected.

Hint 3

Think about what `xargs` does when fed an empty stream, and what signal `kill -9` sends versus `kill -15` (SIGTERM).

Follow-up questions

  • How does `pkill -f` differ from `pkill -x`, and when would PID recycling present a race condition between process discovery and signal delivery?
  • If `$DEPLOY_DIR` is empty or unset, what does `chmod -R 777 $DEPLOY_DIR` do if `set -u` is not enabled?
  • How would you ensure that a backgrounded process spawned in a CI or container environment is properly cleaned up when the parent shell receives `SIGTERM`?