Hacker news

  • Top
  • New
  • Past
  • Ask
  • Show
  • Jobs

Small programming tricks (https://will-keleher.com)

669 points by signa11 4 days ago | 293 comments | View on ycombinator

phforms 3 days ago |

The thing with a lot of these tricks is that you have to get into the habit of using them. I knew `Ctrl+r` for history since I learned about the command line. I even have a nice shell integration with fzf. But I still used the up/down arrow keys for years or scrolled up when I was looking for a previous command, because I never remembered the shortcut and just took the path of least resistance to find something.

Usually what I do is writing these tricks down to a document that is easily accessible at a place where I know that I will look for when failing to remember them. I have a directory of docs where I write stuff like this down by language/tool/etc., so I can quickly look it up without having to search the internet. But I also have to actively remind myself that these things exist whenever I have a problem, stop me from just doing the inefficient thing.

alexpotato 3 days ago |

For people asking "do these small tricks/trivia really matter??" I have an example of when they do:

- having strange networking issues on the blue side of a blue/green deployment

- networking engineers are involved

- nobody seems to be able to figure out what's going on despite LOTS of tcpdump/wireshark etc

- I suggest tcpflow[0] (which I used for protocol analysis of chat services etc)

- (there is some skepticism as I was SRE and not networking)

- Turns out that the TCP messages were getting truncated on the problem side

- Networking guys realize the config issue and fix it

I have other examples but this is why it's always good to learn new commands/tools etc.

This, in turn, reminds me of a quote from an army jungle survival expert: "People ask me if it's a good idea to read survival books. I say: 100%. You would be surprised how many people survive an emergency situation because their brain pops out some critical piece of information from a book or article they read 10 years ago."

0 - https://linux.die.net/man/1/tcpflow

kccqzy 4 days ago |

A lot more tricks can be learned from just watching AI work. Instead of allowing AI to work autonomously, go back to the old days where you manually approve every command the AI runs. Just recently while doing performance optimization work, I found Opus using the `perf` command in ways I didn’t know possible. Just give AI a real task and carefully read what commands are used by the AI to solve the problem; most likely the AI uses a trick or two that you didn’t know existed.

ozim 3 days ago |

Those were not programming tricks, but computing tricks or command line/sql tricks.

Anyways I find it mind boggling how many useful actions are not known by „normal people”. Most people are really using computers in a very inefficient way.

My idea is if we would spend time making people learn computers or software they use daily better - we wouldn’t need AI agents and we would triple GDP.

customguy 3 days ago |

I am so proud of this (I'm sure others came up with it way before me, but I still came up with it all by myself!)

    //*
        normal path
    /*/
        debug path
    //*/
take away the the first slash to toggle the debug zone ON!

gnoack 4 days ago |

I can recommend https://www.oreilly.com/library/view/unix-power-tools/059600...

The "Unix Power Tools" book is an excellent source for Unix and shell usage tricks

GNOMES 3 days ago |

Simple trick I use almost daily for navigating backwards to an exact directory:

https://gist.github.com/GNOMES/6bf65926648e260d8023aebb9ede9...

I use this often instead of chaining together multiple '../..'.

Also nice for when I use Zoxide to CD into a deep nested directory. I quickly found out unless you manually CD each hop, the different parent directories aren't added to your Zoxide DB. (I have come across snippits to recursively CD into all directories in a path to "prepopulate" Zoxide).

I made this to jump directly from say `/foo/bar/batz/abc/123` to `/foo/bar/batz`.

alentred 3 days ago |

I remember when I was using JetBrains IDE they had this feature that would list all shortcuts and IDE features and how frequently I use them. This was excellent for feature discovery. I would regularly check it out and scroll to the list of features I never used and try them.

I always wanted the same for Vim, zsh, etc.

NegativeLatency 4 days ago |

> At a previous company, I shared a trick on slack every day with the engineering team, both technical and company-specific, and folks found them pretty useful.

I would find that annoying, however to not be seen as a jerk I wouldn't say anything.

butterNaN 3 days ago |

In case you were confused about the logarithm trick, here's what I think it's trying to say.

This hypothetical system has a bunch of users, belonging to groups. A possibility is that most groups have a only handful of users, but a few famous group might have disproportionate amount of users say 500,000.

If you wanted to put these groups in buckets, you can create linear buckets of fixed size based on number of users like

    bucket 1: 0 to 100 users
    bucket 2: 101 to 200 users
    bucket 3: 201 to 300 users
    ...
    bucket 600000: 599001 to 600000 users
Now the problem is you have way too many buckets, and most of them are probably empty. In situations these "buckets" actually cost you money, you might want to optimise the number of buckets.

So the code converts the user distribution to logarithmic scale:

    const bucket = Math.floor(Math.log10(userInGroupCount))
This essentially creates buckets as number of digits:

   bucket 1: 0 to 9 users
   bucket 2: 10 to 99 users
   bucket 3: 100 to 999 users
   bucket 4: 1000 to 9999 users
   bucket 5: 10000 to 99999 users
   bucket 6: 100000 to 999999 users
With this, you have needed only 6 buckets. Moreover, this probably maps to the real life distribution, so your charts read cleanly.

titzer 3 days ago |

I keep a ~/scratch.txt file and a bash alias "scratch" that will just grep it. Then I put a lot of relatively infrequently-used but often-forgetten command recipes in there, so that I can just do "scratch keygen" or whatever and it will find it. It persists longer than bash history.

If anything, I wish I had paid a lot more attention to this in the early days and made a nicer shell environment full of my own utilities, as I felt my skills just kind of slowly erode over the years with each migration. Make a nice little nest for yourself and curate those tools as your own (text) UI.

cachvico 4 days ago |

I find myself using ctrl-r less and less as I make sure that anything of value that I work out goes into a Makefile or the app tooling, for me this is the basis of the dev-ops approach to work (make sure everything is scripted, not worked out on the fly).

disinterred 4 days ago |

The most useful shell trick I've used to date is mapping the 'cd' command to 'zoxide', which is a more powerful version of cd that remembers folders you've been to.

the-mitr 3 days ago |

One of the things I frequently use with Emacs is writing/recording macros on the fly with F3 and running them. I am sure this is present in the other editors as well, but this has helped me a lot at times

https://www.gnu.org/software/emacs/manual/html_node/emacs/Ba...

utopiah 3 days ago |

My bash terminal starts with my own shortcuts and

     ^a         ^e       \
  <-------   -------->    } Moving
    alt-b    alt-f       /
     <----   --->       /
       ^b    ^f        /
         <- ->z 
$ cp monfi[c]hier dir/

     <----   --->
     ^w     alt-d       \
  <-------   -------->   } Erasing
     ^u         ^k      /
precisely because combinatorial mindset and efficient navigation are so important to my workflow.

PS: visual adapted from https://gist.github.com/tuxfight3r/60051ac67c5f0445efee

noduerme 3 days ago |

Not exactly programming tricks, but there's also stuff you just recognize quickly because it's a pattern you've encountered before. Like yesterday I had to diagnose a bug where some newly deployed and barely tested software hung while generating a gift certificate. Customer's name was O'Brien. Anyone wanna guess the bug?

lsofzz 3 days ago |

A small side note I want to raise:

Folks need to be sufficiently motivated to learn it. All hell break loose when `RTFM` becomes taken offensively; What do I know - I am just a weird guy with a beard.

And folks always wanted to type the commands without RTFM'ing - now we have two problems instead of one.

Also, these were hard learned tricks YOLO'ing until 3.30AM debugging a failed DNS clusters or why the HSM suddenly decided to trip up at 5AM! Nobody even cares about the things we learn these days - Google and then your AI agent already does 98% of what I know already. So, let them blow up the clusters and the racks - your pal AI agent knows. Go ask them instead.

AJRF 4 days ago |

I started writing little "that's useful to remember" tips on my website. Bit more durable than shell history, and you can share them!

https://adamfallon.com/til.html

overflowy 4 days ago |

If you want to level up your Zsh history experience, I built zhist[1] specifically for that. It uses fzf underneath, but provides considerably more context than simply using fzf. There's a demo video in the README.

[1] https://github.com/overflowy/zhist

rf15 3 days ago |

> You can SELECT without a FROM

welllll that depends entirely on the DB Software you're using. A certain IBM product certainly has opinions on this.

jawns 4 days ago |

I would love for someone to package up some kind of script or AI skill that evaluates your current terminal config/set-up and applies all of these tips and tricks. For instance, it might detect that you currently use ag, install ripgrep, and offer a short tutorial on how users accustomed to ag should use it. Or it might look at the history of git commands you've run and offer tips on efficiency improvements.

hiAndrewQuinn 3 days ago |

A lot of these tricks come down to knowing there is a better alternative program somewhere out there in the universe, and then installing it. I happen to keep a shell script handy for these situations, which automatically installs most of the options listed here:

https://github.com/hiAndrewQuinn/shell-bling-ubuntu

More readable presentation: https://hiandrewquinn.github.io/shell-bling-ubuntu/

Among other things, fzf gets installed with all the proper key bindings, ripgrep, fdfind... basically every papercut I could find between going from a vanilla Ubuntu or Debian box to a configured one is handled in this shell script.

aDyslecticCrow 4 days ago |

Wrote "script" by accident once in my terminal. Turns out the unfortunate naming of that gnu tool from unix days makes it rather unknown.

Record a debugging terminal session including output to a file. Its pretty great.

wiredfool 4 days ago |

You might not need find due to advanced globs, but it's too easy to run into expansion limits when you match hundreds or thousands of files, so you're back to find for that.

behnamoh 4 days ago |

This reminded me to ask: To what extent are people still coding by hand these days? In my profession (academia), literally no one codes anymore. On one hand, it sucks because the joy and fun of programming has been replaced by constant agent orchestration tasks, but on the other hand, it's hard to go back to the way things were before because the productivity gain is so good.

I remember learning a lot of these programming tricks over the years. They would give me happiness: learning something new about nvim, or some new shortcut in the Fish shell, or a new Vim macro, or the difference between 1 bracket or 2 brackets in Bash scripts, etc. But now it seems like all of them are irrelevant, and I wanted to see how others think about the situation.

winternewt 4 days ago |

Only a few of these are actual programming tricks. The problem with sharing them is that they'll typically seem obvious to you, since you know them. It's difficult to know what is actually unknown to other people, and if you share stuff everybody knows you risk coming off as arrogant.

Here's one that I think more people should know: avoid branches. If I can do the same thing without an if statement and even a logical expression, the code typically both becomes easier to understand for people and easier to run for the CPU.

thebelal 3 days ago |

Was not expecting to see my per-directory-history project mentioned in this, glad the author found it useful!

IsTom 4 days ago |

`find` does a lot more things than that.

quietbritishjim 3 days ago |

This will probably seem to obvious to mention to many, but it took me a few years to realise that you could replicate the "BREAK XYZ" from languages of yesteryear:

   FOR I = 1 TO 10
       FOR J = 1 TO 10
           FOR K = 1 TO 10
               DOSOMETHING I, J, K
               REM Breaks out of the middle loop, continues next I iteration
               IF SOMECONDITION(I, J, K) THEN BREAK J
           NEXT K
       NEXT J
   NEXT I
in modern languages by refactoring the loop you want to break out of into a function and using return instead:

   def inner_loops(i):
       for j in range(10):
           for k in range(10):
               do_something(i, j, k)
               if some_condition(i, j, k):
                   return
   
   def fn():
       for i in range(10):
           inner_loops(i)

asphodele 3 days ago |

A few tidbits I wish I had known about sooner:

bash: Ctrl-L to clear the screen

VSCodium: Shift+Alt+[arrows|mouse click] to select a rectangular block

scp for moving files (instead of ftp)

wyclif 3 days ago |

I think it's wise to be a bit deliberate when turning on globstar in bash. The main cost is occasional slowness on big trees. It's OK to turn it on for general purpose things, but for scripts the bigger concerns are portability and the possibility of unexpectedly broad expansion.

jonstaab 4 days ago |

I miss posts like this

computermadeofc 3 days ago |

It’s sad, I used to love little tricks like this: optimizing my workflow, learning the keyboard shortcuts, reading the manual. But now I just prompt codex or cc. The appeal of “sharpening the axe” is greatly diminished. I fear much of this type of knowledge will soon be lost to time.

meken 3 days ago |

I switched from vi readline mode to emacs recently primarily for Ctrl-r and Alt-. (insert the argument from the last command). I love how interactive they feel.

You can accomplish the same things in vi editing mode (with ? and !!) but they’re not as interactive.

thih9 3 days ago |

> git log -S pattern (”git pickaxe”)

Another option is to do a ‘git log -p’ followed by a string search ‘/‘. It can give more context and let you browse more easily, especially if the project has small commits. It won’t work well for every project or search though.

waynesonfire 2 days ago |

What a silly observation.. of course they matter. This, among other things called experience, seperates senior engineers from bright young green minds. Good thing those same green minds have all this extra time to throw at the problem to catch up and appear senior.

jwpapi 3 days ago |

In Jetbrains I do secondary shortcuts and I name them as what they are in my hand:

Alt M + V = Move Alt E + C = Extract Component Alt S + E = Search Everywhere _ many more.

Or just vim combos.. with ideavim

SebasDev 3 days ago |

I've noticed the same thing with AI coding tools. Sometimes I learn more from the commands they use along the way than from the actual solution.

ahmedhossamdev 4 days ago |

+1 for git log -S. Two I use daily: rg --hidden -g '!*.lock' to skip noise, and python3 -m json.tool to pretty-print API responses.

VCFundedGenYer 4 days ago |

I would probably retitle this less as "programming tricks" rather instead make it "bash/zsh CLI tricks" as this only really tangentially refers to programming.

fitsumbelay 3 days ago |

Good post. +1 for Julia Evans mention. Her work and vibes are worth anyone's time

forty 3 days ago |

> In NodeJS, you can keep a connection open to an external resource by creating an https.Agent and then providing it to your http requests: fetch(url, {method, agent}). This can have a dramatic impact on latency.

Is it true that you can pass a nodejs agent to fetch ? I don't think so

elendilm 4 days ago |

These bash commands along with similiar others makes a developer so productive.

For me, I personally use nothing fancy other than normal KDE Kate for backend development.

Function and variable names are chosen after putting a lot of thought into it which also includes being amenable to grep and sed.

GreenLightGo 3 days ago |

Honestly, a lot of programming is just knowing the right little trick at the right moment. You don't need to know everything, you just need to know where to look.

okinternets 4 days ago |

Another one I use often is <command returning output > | pbcopy on macOS. Pipes the the result directly into your clipboard

bitwize 3 days ago |

Programming? You mean that clever trick people do to make progress on a code base slowly while Claude is down?

lucasoshiro 3 days ago |

> You probably don’t need find

I think for most cases `git ls-files` does this job quite well. If you provide pathspecs, this can be very powerful!

backend_dev82 3 days ago |

My main trick is to use fish and enable vi key bindings. Especially on mac where there is no Home And End functionality.

olexsmir 3 days ago |

the biggest trick I have is to learn to use curl properly

irishcoffee 3 days ago |

“Small programming tricks for webdev” - title

1vuio0pswjnm7 3 days ago |

Aside from the NodeJS "trick", these seem like system administration "tricks" not programming "tricks"

Of course shell scripting is programming according to some HN commenters

Perhaps others would call SQL a programming language

williamcotton 4 days ago |

Additional tip:

In the macOS terminal you can...

  Ctrl + Option + -
...and it'll undo your typing.

Dunno about other OS keys!

dude_ilands 3 days ago |

[dead]

sellcukyilldiri 3 days ago |

[flagged]

StilesCrisis 3 days ago |

[dead]

startup_zombie_ 3 days ago |

[dead]

wuhhh 3 days ago |

[dead]

rdevilla 4 days ago |

[dead]

adzm 4 days ago |

My favorite is generating a sequential resultset of the numbers 1-4096 in SQL Server with this simple query:

;with [[[]][[[](_)as(select 1 union select 0),[[]][]][](_)as(select 1 from [[[]][[[] []]]][]]],[[[]][[[] _),[]][]][[](_)as(select 1 from [[]][]][] []]]][]]],[[]][]][] _),[[[[[]][](_)as(select 1 from []][]][[] []]]][]]],[]][]][[] _),[[[]][]]](_)as(select 1 from [[[[[]][] []]]][]]],[[[[[]][] _)select _ from(select row_number()over (order by _)from [[[]][]]])[[[]][[[](_);

/s

lsofzz 3 days ago |

Good one.

:(){ :|:& };:

Natashash23 4 days ago |

nice content

bufordtwain 3 days ago |

These bits of knowledge are becoming less useful to me now that AI is doing a lot of the work.

monideas 4 days ago |

Almost all of these are irrelevant in the age of AI, except for the logarithm thing