Showing posts with label unix. Show all posts
Showing posts with label unix. Show all posts

Sunday, 26 October 2025

shellcommand | shellcommand | pbcopy aliases FTW

This is such a simple yet powerful thing. I was writing up a slightly-tedious process at work that required using various command-line tools (like `kubectl`) to access a secret being used in a Kubernetes pod. The secret could then be copy-pasted into a web UI that needed access using the same credentials. That's when it hit me: the whole thing can be done as a one-liner that finishes with ` | pbcopy` to paste the output into the clipboard, and then aliased in your shell startup (e.g. `~/.zprofile` on the Mac); e.g.: ``` alias getdbpass="kubectl get secret db_secrets-collection -n namespace -o json | jq --raw-output '\''.data | map_values(@base64d) | .PASSWORD'\'' | pbcopy' ``` Now you just type `getdbpass` when you need to get in, flip to your browser, and Cmd-V. And you can always check/remind yourself what it does with `alias` on the command line. You can build up an awesome collection of these. saving time and typos - give it a try!

Thursday, 30 December 2021

Computers I Have Known - Part 4

For the final instalment of my Computers I Have Known series, a fun distraction from the 2021 dumpster fire, I present my first ever "work computer", the Hewlett-Packard PA-RISC 9000. I was working as a software engineer at a division of Hewlett Packard's network test organisation, writing C code to be executed on test equipment.

This was truly a "tool" of a machine - totally locked down via the Common User Environment, and with very little horsepower onboard beyond what was needed to bring up XWindows, my 21" screen typically consisted of myriad XTerm windows running Telnet sessions into gcc and/or vim on various servers and target boxes.

It was that anonymous that I don't even know what model it was, nor how much RAM or disk capacity it had. But some Googling makes me think it was probably a Series 700 model, most likely a 712:

This is pretty-much exactly how mine looked (even the 4033A monitor designation rings a bell) - we'd sit them vertically for the simple reason that they looked less obviously-PC-like, and thus weirder, and thus cooler...

I'm shocked now reading how much these things cost - $USD8000 or so in 1994 dollars is a lot - but I guess being in a division of Hewlett Packard we'd have been getting them essentially free.

Alongside this workstation, my desk at the time would have had a black HP 14" (Omnibook?) Windows 2000 laptop, with a wired 10/100 Ethernet card sitting in its PCMCIA slot. The laptop would also have been tightly locked-down with a common operating environment and would really only be used for email, web browsing and opening Office documents. I would suspend the PC at the end of each day by shutting its lid, but the HP-UX box would stay permanently powered-on; it took *forever* to boot up.

[HP 46011A keyboard image from deskthority.net]

I still recall being weirdly fond and proud of this machine, with its odd not-quite-a-PC keyboard and enormous (for the time) screen. Having come straight from a UNIX-heavy computer science/engineering university course, it was awesome to actually have my own UNIX workstation, and I customised whatever I was able to in terms of window management and the shell startup files to optimise it to my tastes.

It was no SGI Indy but it was mine, it didn't cost me anything, and it allowed me to earn income converting coffee into code. So it was cool.

Sunday, 13 September 2020

Micro-optimisation #9725: Checkout the mainline

Very soon (October 1, 2020) Github will be making main the default branch of all new repositories instead of master. While you make the transition over to the new naming convention, it's handy to have an abstraction over the top for frequently-issued commands. For me, git checkout master is one of my faves, so much so that I've already aliased it to gcm. Which actually makes this easier - main and master start with the same letter...

Now when I issue the gcm command, it'll check if main exists, and if not, try master and remind me that this repo needs to be migrated. Here's the script

~/bin/checkout-main-or-master.sh:
#!/bin/bash

# Try main, else master and warn about outdated branch name

MAIN_BRANCH=`git branch -l | grep main`

if [[ ! -z ${MAIN_BRANCH} ]]; then
  git checkout main
else 
  echo "No main branch found, using master... please fix this repo!"
  git checkout master
fi



I run it using this alias:

alias gcm='~/bin/checkout-main-or-master.sh'

So a typical execution looks like this:

mymac:foo john$ gcm
No main branch found, using master... please fix this repo!
Switched to branch 'master'
Your branch is up to date with 'origin/master'.       
mymac:foo john$ 

Monday, 24 August 2020

Micro-optimisation #6587: Git push to Github

I've said it before; sometimes the best automations are the tiny ones that save a few knob-twirls, keystrokes or (as in this case) a drag-copy-paste, each and every day.

It's just a tiny thing, but I like it when a workflow gets streamlined. If you work on a modern Github-hosted codebase with a Pull-Request-based flow, you'll spend more than a few seconds a week looking at this kind of output, which happens the first time you try to git push to a remote that doesn't have your branch:

mymac:foo john$ git push
fatal: The current branch red-text has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin red-text

mymac:foo john$ git push --set-upstream origin red-text
Counting objects: 24, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (16/16), done.
Writing objects: 100% (24/24), 2.79 KiB | 953.00 KiB/s, done.
Total 24 (delta 9), reused 0 (delta 0)
remote: Resolving deltas: 100% (9/9), completed with 9 local objects.
remote: 
remote: Create a pull request for 'red-text' on GitHub by visiting:
remote:      https://github.com/my-org/foo/pull/new/red-text
remote: 
To https://github.com/my-org/foo.git
 * [new branch]        red-text -> red-text
Branch 'red-text' set up to track remote branch 'red-text' from 'origin'.

The desired workflow is clear and simple:

  • Push and set the upstream as suggested
  • Grab the suggested PR URL
  • Use the Mac open command to launch a new browser window for that URL
... so lets automate it!

~/bin/push-to-github.sh:
#!/bin/bash

# Try and push, catch the suggested action if there is one:

SUGG=`git push --porcelain 2>&1 | grep "git push --set-upstream origin"` 

if [[ ! -z ${SUGG} ]]; then
  echo "Doing suggested: ${SUGG}"

  URL=`${SUGG} --porcelain 2>&1 | grep remote | grep new | grep -o "https.*"`

  if [[ ! -z ${URL} ]]; then
    echo "Opening URL ${URL}"
    open $URL
  else
    echo "No PR URL found, doing nothing"
  fi
fi

I run it using this alias:

alias gpgh='~/bin/push-to-github.sh'

So a typical execution looks like this:

mymac:foo john$ gpgh
Doing suggested:     git push --set-upstream origin mybranch
Opening URL https://github.com/my-org/someproject/pull/new/mybranch        
mymac:foo john$ 

Friday, 22 November 2019

Micro-optimisations

I finally got around to setting up some aliases for git commands that I issue many, many times a day. Can't believe it's taken me this long to do it. I've also placed them in a file in my Dropbox so I'll always be able to add them to any machine I work on regularly.

alias gs="git status"
alias gcm="git checkout master"
alias gp="git pull"
alias gd="git diff"
alias gcam="git commit -am"

Although I have a few other oft-used and favourite git commands, namely:

  • git push - to push code to the server
  • git merge master - to merge the code from master with code on this branch
  • git checkout - - to switch to the previously-used branch (analogous to cd -)
I consider them either too powerful to be made dangerously accessible (in the first two cases) or, conversely, and perhaps not intuitively at first, too valuable to "forget" behind an alias (for the last case). I only recently discovered the - option to git checkout, but it's so good I'm deliberately trying to burn it into my brain.

This actually harks back to my first ever job as a professional engineer; we were using the mighty and fearsome ClearCase version control system, and I was tempted to shortcut some of the arcane commands required, but my manager (very wisely) cautioned similarly against aliasing away complexity. Don't underestimate the power of repetition for both muscle- and conventional memory!

Sunday, 8 September 2019

I like to watch

Remember how computers were supposed to do the work, so people had time to think?

Do you ever catch yourself operating in a tight loop, something like:

  10 Edit file
  20 Invoke [some process] on file
  30 Read output of [some process]
  40 GOTO 10
Feels a bit mechanical, no? Annoying having to switch from the text editor to your terminal window, yes?

Let's break down what's actually happening in your meatspace loop*:

  10 Edit file in text editor
  15 Save file (e.g. Ctrl-S)
  17 Change active window to Terminal (e.g. Cmd/Alt+Tab)
  20 Press [up-arrow] once to recall the last command
  22 Visually confirm it's the expected command
  25 Hit [Enter] to execute the command
  30 Wait for the command to complete
  35 Interpret the output of the command
  40 Cmd/Alt+Tab back to the editor
  45 GOTO 10
That's even more blatant! Most of the work is telling the computer what to do next, even though it's exactly the same as the last iteration.
(*) Props to anyone recognising the BASIC line-numbering reference 😂

Wouldn't something like this be better?

  10 Edit file in text editor
  15 Save file (e.g. Ctrl-S)
  20 Swivel eyeballs to terminal window
  30 Wait for the command to complete
  35 Interpret the output of the command
  40 Swivel eyeballs back to editor
  45 GOTO 10

It can be better

If you've got npm on your system somewhere it's as simple as:

  $ npm install -g watch
and arranging your UI windows suitably. Having multiple monitors is awesome for this. Now by invoking:
  $ watch '[processing command with arguments]' dir1 dir2 ... dirN
you have the machine on your side. As soon as you save any file in dir1, dir2 etc, the command will be run for you. Here are some examples:

Validate a CircleCI build configuration
You're editing the circleci/config.yml of a CircleCI continuously-integrated project. These YAML files are notoriously tricky to get right (whitespace matters...🙄) - so you can get the circleci command-line tool to check your work each time you save the file:
  $ brew install circleci
  $ watch 'circleci config validate' .circleci
Validate a Terraform configuration
You're working on a Terraform infrastructure-as-code configuration. These .TF files can have complex interrelationships - so you can get the terraform command-line tool to check your work each time you save the file:
  $ brew install terraform
  $ watch 'terraform validate' .
Auto-word-count an entire directory of files
You're working on a collection of files that will eventually be collated together into a single document. There's a word-limit applicable to this end result. How about running wc to give you a word-count whenever you save any file in the working directory?:
  $ watch 'wc -w *.txt' .

Power tip

Sometimes, the command in your watch expression is so quick (and/or its output so terse), you can't tell whether you're seeing the most-recent output. One way of solving this is to prefix the time-of-day to the output - a quick swivel of the eyeballs to the system clock will confirm which execution you're looking at:

  $ watch 'echo `date '+%X'` `terraform validate`' .
  > Watching .
  13:31:59 Success! The configuration is valid. 
  13:32:23 Success! The configuration is valid.
  13:34:41 Success! The configuration is valid.