Shell tips
Table of Contents
:ID: 3453ED9D-38E6-4EDA-9652-189BCABA429F
Just some various tips for writing shell scripts or doing cmd line stuff.
# Get the first n lines from STDOUT
We can use the head
program for this. head
will return the first n lines
of a file, but can be used with STDOUT
as well.
Example: get the docker image ID for the last created image.
docker images --format "{{.ID}}" | head -n 1
See also man head
# Forward arguments
Forward all arguments passed to a script to some other program called by the script.
$@
Represents all arguments, so in a script that does something with npm,
for example, we can forward all the arguments passed to the script to npm:
npm $@
# Default arguments
If a parameter is unset or null, use a default value.
See also https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion
npm run test ${FILE_PATH:-'tests/unit/**/*.spec.*(ts|js)'}
We can also set the parameter by using =
instead of -
above.
# List open files
Use lsof
It will include open sockets since anything IO is considered a file on a UNIX OS.
# Examples
# List Internet files
lsof -i
…on a specific port
lsof -i :3000
…or list all processes that are listening on some port
lsof -i -P -n | grep LISTEN
# Test if process is running
Here I wanted to test if reaper was already running before trying to start it.
I don’t want two instances of the program. Note the &
sends it to a subshell
(child process)
if ! [[ "`pidof -x reaper -o %PPID`" ]]; then reaper & fi
# Prevent scripts from going hog wild
Put set -euo pipefail
as the first line of the script
-e
: Fails the entire script if any command has a non-zero exit status (ie, prevent subsequent commands from being executed)-o
: Use the return code of any command that failed in a pipeline, not just the last successful one.-u
: Makes unbound variables throw an error.
# Repeat / for loops
I found this useful to test flaky RSpec tests
for i in {1..5} do echo $i done
# Get info about binary in your path
# whereis
Returns the location of the binary and the man page.
# Look up alias
Use the type
or which
utilities
type grep #=> grep is an alias for grep --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn,.idea,.tox}
# Time how long a command takes
Use the time
utility:
time sleep 1 real 0m1.033s user 0m0.001s sys 0m0.000sp
real
is actual clock timeuser
is CPU time on user processessys
is CPU time on kernel processes
see also https://stackoverflow.com/a/556411
If the real time is much higher compared to CPU times then there is some I/O waiting happening.