AI-Assisted Engineering

Use an AI Agent as Your Shell Front End, Not More Aliases

The graveyard of forgotten shell scripts has an alternative. Describe the task in plain words and let an AI assemble grep, awk, and jq for you.

For years the answer to a repeated command was to save it: an alias, a shell function, a script in ~/bin with a name you would later forget. That habit is now worth questioning. When an AI agent can read plain English and assemble the right pipeline of standard tools on the spot, most of that personal scripting layer stops earning its keep. This post is about where the shift holds, where it does not, and the rule that decides which is which.

The claim is narrow. Scripts are not obsolete. But a large share of the small scripts people write are one-off or rarely-repeated tasks that were only scripted because typing the pipeline by hand was annoying. That annoyance is exactly what an AI front end removes.

The graveyard of forgotten scripts

Look inside any long-lived ~/bin or .zshrc and you find the same pattern. Dozens of aliases and functions, half of them unused, most of them undocumented. You remember gs is git status, but was the log-tailing one called errlog or logtail? You wrote a script six months ago to extract failed requests from an access log. Finding it again takes longer than rewriting it would.

Three costs pile up here. First, you have to remember the name and the argument order, which is a lookup problem you solved by creating more things to look up. Second, you have to maintain them, because a flag changes or a path moves and the script silently breaks. Third, nobody else can read them, so the knowledge lives in one head and dies when that person leaves the team or forgets their own shorthand.

None of these scripts were wrong to write. Each solved a real friction in the moment. The problem is the accumulation. A personal automation layer grows faster than anyone can prune it, and most of it is dead weight within a year.

What driving the shell through an AI looks like

The alternative is to state the intent and let the agent build the command. You do not name a tool or recall a flag. You describe the result you want, and the agent picks grep, awk, jq, find, sort, or whatever fits, runs it, and shows you the output. If the first attempt is off, you correct it in words rather than in syntax.

Here is the shape of it, as intent on the left and the kind of pipeline the agent assembles on the right.

What you say What the agent runs
pull the errors from last week's logs and summarize them in three lines grep -i error app.log filtered by date range, then the agent reads and summarizes
which processes are using the most memory right now ps aux | sort -nrk4 | head
count the unique IP addresses in the access log awk '{print $1}' access.log | sort -u | wc -l
how big is each subfolder here, largest first du -sh */ | sort -rh
find every TODO comment added this month git log --since='1 month ago' -p | grep '+.*TODO'
rename these files, spaces to hyphens a for loop with mv "$f" "${f// /-}"
show me the 10 largest files under this tree find . -type f -printf '%s %p\n' | sort -nr | head

Notice what is on the left: plain requests, none of which you had to memorize. The tools on the right are the ones a seasoned shell user already knows, but knowing them and recalling the exact flag under time pressure are different skills. The agent covers the recall. You keep the judgment about whether the output is right.

The summarizing case is the one a raw script cannot match. grep can pull the error lines, but turning a hundred stack traces into three sentences that say what actually failed is language work. A pipeline plus a language model in the same loop does something neither half does alone.

Why standard tools are the AI's home turf

This works because of what the AI is being asked to do. The Unix toolset is small, old, and documented to death. grep, sed, awk, find, sort, jq, and the shells that glue them together have been stable for decades and described in millions of examples. When a model assembles a pipeline from these parts, it is working inside one of the best-covered domains it has. The commands are composable by design, so the model is snapping together known pieces rather than inventing anything.

Compare that to asking a model to write a novel algorithm or navigate a private, undocumented internal API. There it has little to stand on and the error rate climbs. Shell composition sits at the opposite end. The building blocks are public, the composition rules are simple, and a wrong guess usually fails loudly and cheaply rather than silently.

There is a second reason it fits. The more one-off and variable the task, the worse a script serves it and the better delegation does. A script pays for itself only when the same exact operation repeats often enough to amortize the cost of writing and maintaining it. Most shell needs are not like that. They are slightly different every time: a different date range, a different field, a different file. Natural language absorbs that variation for free, while a script would need a new flag or a rewrite for each variant.

When a script still wins

Delegation is not the answer for everything, and pretending it is leads to the opposite mistake. A written script beats a natural-language request in a few clear cases.

  • High-frequency repetition. If you run the same operation twenty times a day, the round trip of describing it in words each time is slower than a two-character alias. Fixed, frequent, identical operations are what aliases were made for. Keep those.
  • Exact reproducibility. When the same command must run the same way every time, in a cron job, a deploy step, or a CI pipeline, you want the literal command pinned in a file, not reassembled from a prompt that might come out slightly different.
  • Correctness-critical pipelines. Anything where a subtle variation would corrupt data or produce a wrong result belongs in a reviewed, version-controlled script. The value there is not convenience, it is that the exact steps are fixed and auditable.
  • Shared, named workflows. A deploy step that the whole team relies on should have one canonical form with a name, not live in each person's phrasing.

The pattern is simple. Scripts are for what is stable, frequent, and must not vary. Delegation is for what is exploratory, occasional, and different every time. The old advice, "you should turn that into a script," was right when most repeated work fell into the first bucket. It is wrong when the work is a moving target that never repeats the same way twice.

The dangerous-command problem

Handing command assembly to an AI raises an obvious risk: a model can build the wrong command, and some wrong commands delete or overwrite data. This is real and it sets the boundary of the whole approach.

The guardrails are the same ones a careful engineer already uses. Destructive operations get a human review before they run. A request that would delete files, overwrite a database, force-push a branch, or change permissions should never execute on the model's word alone. You read the command first, confirm it does what you meant, and only then let it run. A good agent surfaces the command and pauses on anything irreversible rather than firing it blind.

Read-only and easily-reversible work is where delegation runs freely. Listing, counting, searching, summarizing, and inspecting cannot hurt anything, so there is little reason to gate them. The mental split is between commands that observe and commands that change. Observing, let it run. Changing, look before you leap.

Verification matters even for non-destructive work. A model can assemble a pipeline that runs cleanly and still answers the wrong question, an off-by-one in a date filter or the wrong column in an awk field. The output is not automatically correct because it was produced confidently. Treat the result the way you would treat a colleague's quick script: useful, probably right, worth a glance before you trust it with anything that counts.

Reproducibility still needs a record

The one thing a conversation does not give you is a durable record. If a task matters enough to run again the same way, or to hand to someone else, or to explain in a postmortem, the words you typed into a chat are not a reliable artifact. They are gone, or buried, and the model might phrase the command differently next time.

So the honest position is not "delete all your scripts." It is that the trigger for writing something down changes. You no longer script a task just because typing it once is tedious. You write it down when it needs to be reproducible: when it will run unattended, when others depend on it, when the exact steps must survive. At that point you promote the throwaway pipeline into a real script or a documented note, ideally by asking the agent to save the exact command it just ran. The agent is good at that too, turning the successful one-off into a named, committed script once you decide it has earned a name.

This keeps the best of both. Exploratory and rare work stays in natural language, fast and disposable. Anything that graduates to load-bearing gets pinned in a file with a name, exactly as before. The difference is that far fewer tasks make that jump than the old habit assumed.

The rule I settled on

Say the intent, keep the tools out of your head, and write down only what must be reproduced.

For the constant, exploratory, slightly-different-every-time work that fills most of a day at the shell, describing the result and letting the agent compose the pipeline is faster and lighter than maintaining a personal script museum. For the stable, frequent, correctness-critical, shared work, keep the explicit script, because there the whole point is that the steps do not vary.

The question that sorts any task is whether it will repeat the same way. If it will, and often, pin it. If it will not, do not build a tool you will forget the name of. Ask for the outcome, check the command before anything destructive runs, and let the shell's oldest, best-documented tools do what they have always done, now with a translator in front of them.

Related posts