<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eya</title>
    <description>The latest articles on DEV Community by Eya (@eyalachhab).</description>
    <link>https://dev.to/eyalachhab</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3904863%2Fceade16a-f29c-4f0b-8fa9-a873f84f0f70.JPG</url>
      <title>DEV Community: Eya</title>
      <link>https://dev.to/eyalachhab</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eyalachhab"/>
    <language>en</language>
    <item>
      <title>Unix commands that feel like cheating — and why most devs have never heard of them</title>
      <dc:creator>Eya</dc:creator>
      <pubDate>Wed, 29 Apr 2026 19:02:42 +0000</pubDate>
      <link>https://dev.to/eyalachhab/unix-commands-that-feel-like-cheating-and-why-most-devs-have-never-heard-of-them-3o80</link>
      <guid>https://dev.to/eyalachhab/unix-commands-that-feel-like-cheating-and-why-most-devs-have-never-heard-of-them-3o80</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;You know &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;. You've read the same "10 useful terminal commands" articles written since 2009. This isn't that. These are the commands that change how you think about the terminal — the ones that make a task you'd normally open Python for take 8 seconds instead.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Command 01 — &lt;code&gt;pv&lt;/code&gt;: pipe viewer, or "why is this taking forever?"
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"I was copying a 40GB database dump over SSH. Zero feedback. Just a blinking cursor for 25 minutes. I had no idea if it was stuck, slow, or done. I killed it twice by accident and had to start over."&lt;br&gt;
— every backend engineer, at least once&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;pv&lt;/code&gt; inserts into any pipe and gives you a live progress bar, transfer rate, ETA, and bytes transferred. It's invisible to the data — it just watches and reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;pv        &lt;span class="c"&gt;# macOS&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;pv         &lt;span class="c"&gt;# Debian/Ubuntu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Compress a large file with progress&lt;/span&gt;
pv hugefile.sql | &lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; hugefile.sql.gz

&lt;span class="c"&gt;# Copy with progress bar&lt;/span&gt;
pv source.tar.gz &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /backup/source.tar.gz

&lt;span class="c"&gt;# Pipe through multiple commands&lt;/span&gt;
pv dump.sql | &lt;span class="nb"&gt;gzip&lt;/span&gt; | ssh user@remote &lt;span class="s2"&gt;"cat &amp;gt; dump.sql.gz"&lt;/span&gt;

&lt;span class="c"&gt;# Throttle transfer rate to 1MB/s&lt;/span&gt;
pv &lt;span class="nt"&gt;-L&lt;/span&gt; 1m source.iso &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use &lt;code&gt;pv -petra&lt;/code&gt; for all metrics at once: progress, ETA, timer, rate, and bytes. Paste that alias into your shell config.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Result: never fly blind on a long pipe again.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Command 02 — &lt;code&gt;moreutils&lt;/code&gt;: vipe, sponge, chronic — the toolkit nobody installs
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"I needed to edit the middle of a pipeline — transform some JSON, hand-fix two records, then pass it on. I ended up saving to a temp file, opening it, editing, piping again. Four steps for something that should've been one."&lt;br&gt;
— a data engineer mid-ETL&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;moreutils&lt;/code&gt; is a collection of Unix tools that should have existed from the start. Three standouts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;moreutils
apt &lt;span class="nb"&gt;install &lt;/span&gt;moreutils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;vipe&lt;/code&gt; — edit mid-pipe
&lt;/h3&gt;

&lt;p&gt;Opens your &lt;code&gt;$EDITOR&lt;/code&gt; in the middle of a pipe. Edit stdin, save, and the result continues down the pipe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate JSON, hand-edit it, then process it&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; api.example.com/data | vipe | jq &lt;span class="s1"&gt;'.results[]'&lt;/span&gt;

&lt;span class="c"&gt;# Filter a log, manually tweak some lines, send to file&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;app.log | &lt;span class="nb"&gt;grep &lt;/span&gt;ERROR | vipe &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; errors-reviewed.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;sponge&lt;/code&gt; — safe in-place editing
&lt;/h3&gt;

&lt;p&gt;Reads all stdin before writing to the output file. Lets you safely read and write the same file in one command — something &lt;code&gt;&amp;gt;&lt;/code&gt; will silently destroy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# DANGEROUS — truncates file before sort finishes reading it&lt;/span&gt;
&lt;span class="nb"&gt;sort &lt;/span&gt;file.txt &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; file.txt

&lt;span class="c"&gt;# SAFE — sponge buffers everything first&lt;/span&gt;
&lt;span class="nb"&gt;sort &lt;/span&gt;file.txt | sponge file.txt

&lt;span class="c"&gt;# Deduplicate a file in place&lt;/span&gt;
&lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; config.txt | sponge config.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;chronic&lt;/code&gt; — silent success, loud failure
&lt;/h3&gt;

&lt;p&gt;Runs a command silently on success, but shows full output on failure. Built for cron jobs — no more noisy emails for commands that succeed 99% of the time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In crontab — only emails you if backup fails&lt;/span&gt;
0 2 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; chronic /usr/local/bin/run-backup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result: three commands that patch real Unix gaps.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Command 03 — &lt;code&gt;fd&lt;/code&gt;: find, but written for humans
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"I've been using &lt;code&gt;find&lt;/code&gt; for 8 years and I still google the syntax every single time. The flags are backwards, case sensitivity is opt-in, and ignoring node_modules requires a paragraph of shell."&lt;br&gt;
— a senior engineer who finally switched&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;fd&lt;/code&gt; is a modern replacement for &lt;code&gt;find&lt;/code&gt;. It's faster (parallel by default), respects &lt;code&gt;.gitignore&lt;/code&gt;, is case-insensitive by default, and has sane syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# find — search for JS files, ignore node_modules&lt;/span&gt;
find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.js"&lt;/span&gt; &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"*/node_modules/*"&lt;/span&gt;

&lt;span class="c"&gt;# fd — same thing&lt;/span&gt;
fd &lt;span class="nt"&gt;-e&lt;/span&gt; js

&lt;span class="c"&gt;# fd — find files modified in the last 2 days&lt;/span&gt;
fd &lt;span class="nt"&gt;--changed-within&lt;/span&gt; 2d

&lt;span class="c"&gt;# fd — find and execute a command on each result&lt;/span&gt;
fd &lt;span class="nt"&gt;-e&lt;/span&gt; log &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;

&lt;span class="c"&gt;# fd — search hidden files too&lt;/span&gt;
fd &lt;span class="nt"&gt;-H&lt;/span&gt; .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; &lt;code&gt;fd&lt;/code&gt; uses regex by default. Pass &lt;code&gt;-g&lt;/code&gt; for glob patterns if that's more natural for the task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; On some systems &lt;code&gt;fd&lt;/code&gt; is installed as &lt;code&gt;fdfind&lt;/code&gt; to avoid a naming conflict. Alias it: &lt;code&gt;alias fd=fdfind&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Result: never google find syntax again.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Command 04 — &lt;code&gt;hyperfine&lt;/code&gt;: benchmarking that's actually rigorous
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"I was arguing with a teammate about which implementation was faster. We were doing &lt;code&gt;time ./script_a&lt;/code&gt; and &lt;code&gt;time ./script_b&lt;/code&gt; back and forth. The results bounced around by 30% depending on system load. We had no idea which was actually faster."&lt;br&gt;
— an engineer mid code-review argument&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;hyperfine&lt;/code&gt; runs commands multiple times, warms up the cache, computes mean and standard deviation, and gives you a statistically meaningful comparison. It's what &lt;code&gt;time&lt;/code&gt; should have been.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;hyperfine
cargo &lt;span class="nb"&gt;install &lt;/span&gt;hyperfine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Benchmark a single command (10 runs by default)&lt;/span&gt;
hyperfine &lt;span class="s1"&gt;'grep -r "TODO" src/'&lt;/span&gt;

&lt;span class="c"&gt;# Compare two implementations&lt;/span&gt;
hyperfine &lt;span class="s1"&gt;'python parse_v1.py data.json'&lt;/span&gt; &lt;span class="s1"&gt;'python parse_v2.py data.json'&lt;/span&gt;

&lt;span class="c"&gt;# Warm up first, then benchmark&lt;/span&gt;
hyperfine &lt;span class="nt"&gt;--warmup&lt;/span&gt; 3 &lt;span class="s1"&gt;'./build/server --dry-run'&lt;/span&gt;

&lt;span class="c"&gt;# Export results to markdown table&lt;/span&gt;
hyperfine &lt;span class="nt"&gt;--export-markdown&lt;/span&gt; results.md &lt;span class="s1"&gt;'cmd_a'&lt;/span&gt; &lt;span class="s1"&gt;'cmd_b'&lt;/span&gt;

&lt;span class="c"&gt;# Run with different input parameters&lt;/span&gt;
hyperfine &lt;span class="s1"&gt;'sort -n {input}'&lt;/span&gt; &lt;span class="nt"&gt;--parameter-list&lt;/span&gt; input small.txt medium.txt large.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use &lt;code&gt;--export-json&lt;/code&gt; to pipe results into your own analysis. Pairs well with &lt;code&gt;jq&lt;/code&gt; for custom reporting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Result: win every "which is faster" argument with data.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Command 05 — &lt;code&gt;atool&lt;/code&gt;: one command for every archive format
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Someone sent me a &lt;code&gt;.tar.bz2&lt;/code&gt;. I couldn't remember if it was &lt;code&gt;-xjf&lt;/code&gt; or &lt;code&gt;-xzf&lt;/code&gt;. I guessed wrong, it failed silently, and I spent 10 minutes wondering why the directory was empty."&lt;br&gt;
— a dev on their third Stack Overflow tab&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;atool&lt;/code&gt; wraps tar, zip, rar, 7z, bz2, xz — every format — behind four consistent commands. You never look up flags again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;atool
apt &lt;span class="nb"&gt;install &lt;/span&gt;atool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The only four commands you need:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Extract anything — format auto-detected&lt;/span&gt;
aunpack archive.tar.bz2
aunpack archive.zip
aunpack archive.7z

&lt;span class="c"&gt;# List contents without extracting&lt;/span&gt;
als archive.tar.gz

&lt;span class="c"&gt;# Create an archive (format from extension)&lt;/span&gt;
apack output.tar.gz file1 file2 &lt;span class="nb"&gt;dir&lt;/span&gt;/

&lt;span class="c"&gt;# Repack from one format to another&lt;/span&gt;
arepack old.tar.gz new.tar.xz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result: one muscle memory. Every archive format. Forever.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Command 06 — &lt;code&gt;entr&lt;/code&gt;: run any command when files change
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"I was writing a C utility with no build tool, no webpack, no hot reload. Every edit meant switching windows, pressing up-arrow, enter. After the 40th time I started looking for a way to automate it. Turns out it already existed."&lt;br&gt;
— a systems programmer who found entr at 2am&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;entr&lt;/code&gt; watches a list of files and re-runs any command when they change. No config file, no daemon, no 500-line Makefile. Just a pipe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;entr
apt &lt;span class="nb"&gt;install &lt;/span&gt;entr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Re-run tests when any Go file changes&lt;/span&gt;
find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'*.go'&lt;/span&gt; | entr go &lt;span class="nb"&gt;test&lt;/span&gt; ./...

&lt;span class="c"&gt;# Recompile on any C file change&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.c | entr make

&lt;span class="c"&gt;# Restart server on source change&lt;/span&gt;
&lt;span class="nb"&gt;ls &lt;/span&gt;src/&lt;span class="k"&gt;**&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;.js | entr &lt;span class="nt"&gt;-r&lt;/span&gt; node server.js

&lt;span class="c"&gt;# Clear screen before each run&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.py | entr &lt;span class="nt"&gt;-c&lt;/span&gt; python main.py

&lt;span class="c"&gt;# Watch a directory recursively (combine with fd)&lt;/span&gt;
fd &lt;span class="nt"&gt;-e&lt;/span&gt; ts | entr &lt;span class="nt"&gt;-rc&lt;/span&gt; npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; &lt;code&gt;-r&lt;/code&gt; kills and restarts a long-running process. &lt;code&gt;-c&lt;/code&gt; clears the screen. &lt;code&gt;-d&lt;/code&gt; exits when a new file is added to the watched set — useful in scripts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Result: hot reload for literally anything.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;None of these are in the standard curriculum. None of them show up in "learn Linux" courses. They exist in blog posts, dotfiles repos, and the &lt;code&gt;.bashrc&lt;/code&gt; of engineers who've been quietly shipping faster than everyone else for years. Now you have them too.&lt;/p&gt;

&lt;p&gt;Install one today. Add it to your dotfiles. Then forget you ever lived without it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found one you didn't know? Drop a comment with your own hidden gem — I'll add the best ones to a follow-up post.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>terminal</category>
      <category>productivity</category>
      <category>unix</category>
    </item>
  </channel>
</rss>
