This is exactly the kind of stuff I'm most interested in finding on HN. How do other developers work, and how can I get better at my work from it?
What's always interesting to me is how many of these I'll see and initially think, "I don't really need that." Because I'm well aware of the effect (which I'm sure has a name - I suppose it's similar to induced demand) of "make $uncommon_task much cheaper" -> "$uncommon_task becomes the basis of an entirely new workflow/skill". So I'm going to try out most of them and see what sticks!
Also: really love the style of the post. It's very clear but also includes super valuable information about how often the author actually uses each script, to get a sense ahead of time for which ones are more likely to trigger the effect described above.
A final aside about my own workflows which betrays my origins... for some of these operations and for others i occasionally need, I'll just open a browser dev tools window and use JS to do it, for example lowercasing a string :)
This is one of the things I miss the most about hacker conferences. The sharing of tools, scripts, tips and tricks. It was, and still is, just as fun as trading cards.
I love this kind of stuff too, but too many times over the years I've found myself in environments without some of these higher level and more niche tools (including my own dot files), or the tool ends up abandoned, and I struggle to remember how to use the basics/builtins. I've gotten a lot more conservative about adopting them because of that.
It's weird how the circle of life progresses for a developer or whatever.
- When I was a fresh engineer I used a pretty vanilla shell environment
- When I got a year or two of experience, I wrote tons of scripts and bash aliases and had a 1k+ line .bashrc the same as OP
- Now, as a more tenured engineer (15 years of experience), I basically just want a vanilla shell with zero distractions, aliases or scripts and use native UNIX implementations. If it's more complicated than that, I'll code it in Python or Go.
For the Infra Engineers out there who still manage fleets of pets, this is double true. You may not have access or be able to use all your shortcut scripts so you better know the raw commands on that unsupported RHEL6 host.
Nice. I have a bash script similar to the one listed "removeexif" called prep_for_web which takes any image file (PNG, BMP, JPG, WebP), scrubs EXIF data, checks for transparency and then compresses it to either JPG using MozJPEG or to PNG using PNGQuant.
Some cool things here but in general I like to learn and use the standard utilities for most of this. Main reason is I hop in and out of a lot of different systems and my personal aliases and scripts are not on most of them.
sed, awk, grep, and xargs along with standard utilities get you a long long way.
Historical note: getting hold of these scripts by chatting to various developers was the motivation for the original 2004 "lifehacks" talk[1][2]. If you ever get into an online argument over what is a "life hack" and what isn't, feel free to use short scripts like these as the canonical example.
Otherwise, I am happy to be pulled into your discussion, Marshall McLuhan style[3] to adjudicate, for a very reasonable fee.
As a bonus, I prepend my custom aliases or scripts with my user name and hyphen (i.e helicaltwine-). It helps me recall rarely used scripts when I need them and forget the names.
if you use x0vnc (useful if you use a linux machine both from the attached screen and from vnc, and in a bunch of other scenarios), copy and paste to and fro the vnc client is not implemented, quite frustrating. here's 2 scripts that does that for you, I now use this all day. https://github.com/francoisp/clipshare
> trash a.txt b.png moves `a.txt` and `b.png` to the trash. Supports macOS and Linux.
The way you’re doing it trashes files sequentially, meaning you hear the trashing sound once per file and ⌘Z in the Finder will only restore the last one. You can improve that (I did it for years) but consider just using the `trash` commands which ships with macOS. Doesn’t use the Finder, so no sound and no ⌘Z, but it’s fast, official, and still allows “Put Back”.
> jsonformat takes JSON at stdin and pretty-prints it to stdout.
Why prioritise node instead of jq? The latter is considerably less code and even comes preinstalled with macOS, now.
> uuid prints a v4 UUID. I use this about once a month.
Any reason to not simply use `uuidgen`, which ships with macOS and likely your Linux distro?
> Why prioritise node instead of jq? The latter is considerably less code and even comes preinstalled with macOS, now.
That was my thought. I use jq to pretty print json.
What I have found useful is j2p and p2j to convert to/from python dict format to json format (and pretty print the output). I also have j2p_clip and p2j_clip, which read from and then write to the system clipboard so I don't have to manually pipe in and out.
> Any reason to not simply use `uuidgen`, which ships with macOS and likely your Linux distro?
I also made a uuid, which just runs uuidgen, but then trims the \n. (And maybe copied to clipboard? It was at my old job, and I don't seem to have saved it to my personal computer.)
Broadly, I very much love this approach to things and wish it was more "acceptable?" It reminds me of the opposite of things like "the useless use of cat" which to me is one of the WORST meme-type-things in this space.
Like, it's okay -- even good -- for the tools to bend to the user and not the other way around.
I have mkcd exactly ( I wonder how many of us do, it's so obvious)
I have almost the same, but differently named with scratch(day), copy(xc), markdown quote(blockquote), murder, waitfor, tryna, etc.
I used to use telegram-send with a custom notification sounnd a lot for notifications from long-running scripts if I walked away from the laptop.
I used to have one called timespeak that would speak the time to me every hour or half hour.
I have go_clone that clones a repo into GOPATH which I use for organising even non-go projects long after putting go projects in GOPATH stopped being needed.
I liked writing one-offs, and I don't think it's premature optimization because I kept getting faster at it.
> cpwd copies the current directory to the clipboard. Basically pwd | copy. I often use this when I’m in a directory and I want use that directory in another terminal tab; I copy it in one tab and cd to it in another. I use this once a day or so.
You can configure your shell to notify the terminal of directory changes, and then use your terminal’s “open new window” function (eg: ctrl+shift+n) to open a new window retaining the current directory.
An important advantage of aliases was not mentioned: I see everything in one place and can easily build aliases on top of other aliases without much thinking.
Anyways, my favourite alias that I use all the time is this:
alias a='nvim ~/.zshrc && . ~/.zshrc'
It solves the ,,not loaded automatically'' part at least for the current terminal
I keep meaning to generalize this (directory target, multiple sources, flags), but I get quite a bit of mileage out of this `unmv` script even as it is:
#!/bin/sh
if test "$#" != 2
then
echo 'Error: unmv must have exactly 2 arguments'
exit 1
fi
exec mv "$2" "$1"
As a programmer, you sometimes want to make an alphabet lookup table. So, something like:
var alpha_lu = "abcdefghijklmnopqrstuvwxyz";
Typing it out by hand is error prone as it's not easy to see if you've swapped the order or missed a character.
I've needed the alphabet string or lookup rarely, but I have needed it before. Some applications could include making your own UUID function, making a small random naming scheme, associating small categorical numbers to letters, etc.
The author of article mentioned they do web development, so it's not hard to imagine they've had to create a URL shortener, maybe more than once. So, for example, creating a small name could look like:
function small_name(len) {
let a = "abcdefghijklmnopqrstuvwxyz",
v = [];
for (let i=0; i<len; i++) {
v.push( a[ Math.floor( Math.random()*a.length ) ] );
}
return v.join("");
}
//...
small_name(5); // e.g. "pfsor"
Dealing with strings, dealing with hashes, random names, etc., one could imagine needing to do functions like this, or functions that are adjacent to these types of tasks, at least once a month.
In fish, I have an abbreviation that automatically expands double dots into ../ so that you can just spam double dots and visually see how far you're going.
# Modified from
# https://github.com/fish-shell/fish-shell/issues/1891#issuecomment-451961517
function append-slash-to-double-dot -d 'expand .. to ../'
# Get commandline up to cursor
set -l cmd (commandline --cut-at-cursor)
# Match last line
switch $cmd[-1]
case '*.'
commandline --insert './'
case '*'
commandline --insert '.'
end
end
I used to do this, but unary kind of sucks after 3; So maybe others might like this better before their fingers get trained:
..() { # Usage: .. [N=1] -> cd up N levels
local d="" i
for ((i = 0; i < ${1:-"1"}; i++))
d="$d/.." # Build up a string & do 1 cd to preserve dirstack
[[ -z $d ]] || cd ./$d
}
Of course, what I actually have been doing since the early 90s is realize that a single "." with no-args is normally illegal and people "cd" soooo much more often than sourcing script definitions. So, I hijack that to save one "." in the first 3 cases and then take a number for the general case.
# dash allows non-AlphaNumeric alias but not function names; POSIX is silent.
cd1 () { if [ $# -eq 0 ]; then cd ..; else command . "$@"; fi; } # nice "cd .."
alias .=cd1
cdu() { # Usage: cdu [N=2] -> cd up N levels
local i=0 d="" # "." already does 1 level
while [ $i -lt ${1:-"2"} ]; do d=$d/..; i=$((i+1)); done
[ -z "$d" ] || cd ./$d; }
alias ..=cdu
alias ...='cd ../../..' # so, "."=1up, ".."=2up, "..."=3up, ".. N"=Nup
and as per the comment this even works in lowly dash, but needs a slight workaround. bash can just do a .() and ..() shell function as with the zsh.
146 comments
[ 1.1 ms ] story [ 98.0 ms ] threadThere also some very niche stuff that I won't use but found funny
What's always interesting to me is how many of these I'll see and initially think, "I don't really need that." Because I'm well aware of the effect (which I'm sure has a name - I suppose it's similar to induced demand) of "make $uncommon_task much cheaper" -> "$uncommon_task becomes the basis of an entirely new workflow/skill". So I'm going to try out most of them and see what sticks!
Also: really love the style of the post. It's very clear but also includes super valuable information about how often the author actually uses each script, to get a sense ahead of time for which ones are more likely to trigger the effect described above.
A final aside about my own workflows which betrays my origins... for some of these operations and for others i occasionally need, I'll just open a browser dev tools window and use JS to do it, for example lowercasing a string :)
A password or token generator, simple or complicated random text.
Scripts to list, view and delete mail messages inside POP3 servers
n, to start Nautilus from terminal in the current directory.
lastpdf, to open the last file I printed as PDF.
lastdownload, to view the names of the n most recent files in the Downloads directory.
And many more but those are the ones that I use often and I remember without looking at ~/bin
- When I was a fresh engineer I used a pretty vanilla shell environment
- When I got a year or two of experience, I wrote tons of scripts and bash aliases and had a 1k+ line .bashrc the same as OP
- Now, as a more tenured engineer (15 years of experience), I basically just want a vanilla shell with zero distractions, aliases or scripts and use native UNIX implementations. If it's more complicated than that, I'll code it in Python or Go.
[1] https://github.com/mozilla/mozjpeg
[2] https://pngquant.org
sed, awk, grep, and xargs along with standard utilities get you a long long way.
Otherwise, I am happy to be pulled into your discussion, Marshall McLuhan style[3] to adjudicate, for a very reasonable fee.
[1] https://craphound.com/lifehacksetcon04.txt
[2] https://archive.org/details/Notcon2004DannyOBrienLifehacks
[3] https://www.openculture.com/2017/05/woody-allen-gets-marshal...
The way you’re doing it trashes files sequentially, meaning you hear the trashing sound once per file and ⌘Z in the Finder will only restore the last one. You can improve that (I did it for years) but consider just using the `trash` commands which ships with macOS. Doesn’t use the Finder, so no sound and no ⌘Z, but it’s fast, official, and still allows “Put Back”.
> jsonformat takes JSON at stdin and pretty-prints it to stdout.
Why prioritise node instead of jq? The latter is considerably less code and even comes preinstalled with macOS, now.
> uuid prints a v4 UUID. I use this about once a month.
Any reason to not simply use `uuidgen`, which ships with macOS and likely your Linux distro?
https://www.man7.org/linux/man-pages/man1/uuidgen.1.html
That was my thought. I use jq to pretty print json.
What I have found useful is j2p and p2j to convert to/from python dict format to json format (and pretty print the output). I also have j2p_clip and p2j_clip, which read from and then write to the system clipboard so I don't have to manually pipe in and out.
> Any reason to not simply use `uuidgen`, which ships with macOS and likely your Linux distro?
I also made a uuid, which just runs uuidgen, but then trims the \n. (And maybe copied to clipboard? It was at my old job, and I don't seem to have saved it to my personal computer.)
Like, it's okay -- even good -- for the tools to bend to the user and not the other way around.
I have almost the same, but differently named with scratch(day), copy(xc), markdown quote(blockquote), murder, waitfor, tryna, etc.
I used to use telegram-send with a custom notification sounnd a lot for notifications from long-running scripts if I walked away from the laptop.
I used to have one called timespeak that would speak the time to me every hour or half hour.
I have go_clone that clones a repo into GOPATH which I use for organising even non-go projects long after putting go projects in GOPATH stopped being needed.
I liked writing one-offs, and I don't think it's premature optimization because I kept getting faster at it.
You can configure your shell to notify the terminal of directory changes, and then use your terminal’s “open new window” function (eg: ctrl+shift+n) to open a new window retaining the current directory.
^ (jump to the beginning)
ctrl+v (block selection)
j (move cursor down)
shift+i (bulk insert?)
type ><space>
ESC
I use this as a bookmarklet to grab the front page of the new york times (print edition). (You can also go back to any date up to like 2011)
I think they go out at like 4 am. So, day-of, note that it will fail if you're in that window before publishing.
Anyways, my favourite alias that I use all the time is this:
It solves the ,,not loaded automatically'' part at least for the current terminalI genuinely wonder, why would anyone want to use this, often?
I've needed the alphabet string or lookup rarely, but I have needed it before. Some applications could include making your own UUID function, making a small random naming scheme, associating small categorical numbers to letters, etc.
The author of article mentioned they do web development, so it's not hard to imagine they've had to create a URL shortener, maybe more than once. So, for example, creating a small name could look like:
Dealing with strings, dealing with hashes, random names, etc., one could imagine needing to do functions like this, or functions that are adjacent to these types of tasks, at least once a month.Just a guess on my part though.
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias .....='cd ../../../..'
alias ......='cd ../../../../..'
alias .......='cd ../../../../../..'