Pass all bash script args to command in script


Use "$@"

npx command_in_package_json "$@"

Which Terminal App am I Using?


macosx has full disk permissions limiting access to certain directories and files. If one app, say iTerm has access but another program does not, say xterm, a bash script might need to check which application can be run with the appropriate permissions.


$ env | grep TERM_
# or in a script
if [[ $TERM_PROGRAM != '' ]]; then
  echo "You need to run this with iTerm for full disk permissions"

Accessing previous bash command arguments


!! for the previous command

!$ for the last argument of the previous command

!^ for the first argument of the previous command

!* for all the arguments of the previous command, pipes (|) count as an argument

!:n for the nth argument

# the previous command, use !!
$ ls -al foo/*
$ !!
ls -al foo/*
# last argument of the previous command, use !$
$ mv author_controller.rb  authors_controller.rb
$ git add !$
git add authors_controller.rb 
# all the arguments of the previous command, use !*
$ ls app/models/author.rb app/models/author.rb.orig
app/models/author.rb       app/models/author.rb.orig
$! ls -al !*
-rw-r--r--  1 kitt  staff  3229 Feb 20 16:18 app/models/author.rb
-rw-r--r--  1 kitt  staff  3229 Feb 20 15:26 app/models/author.rb.orig
# get the nth argument of the previous command, use !:n
$ cat /usr/share/dict/words | grep -o -w '\w\{5\}'
$ echo !:3

What Shell am I Using?


How to figure out what shell you're using.

ps -p $$

Compare two folders for differences


-a treats all files as text, -r recursively searched subdirectories, -q reports 'briefly', only when files differ

diff -arq folder1 folder2

pushd popd dirs

# push a directory onto the stack
pushd {dir}
# pop the last directory off the stack, change to the next directory in the stack
# view the stack in a numbered list
dirs -v 
# pull the nth directory out of the stack, put it at the top, and change to it
pushd +n
# remove the nth directory from the stack, don't change to it or anything
popd +n

Saving command line history


Alan Schussman asks "Is there a word for when you have to reboot for software updates, but have a ton of terminal tabs with a month’s work of personal project history in them that maybe, just maybe I’ll need someday?"

To which I say, "Frustrating."

I have these two bash functions to save and find commands I've run (yes, I have a history going back a large number of years).

$ hsave to save history.
$ sg COMMAND to find how I ran that command before.

Add it to the ~/.bash_logout script, and the terminal's history should save when you close a terminal. I have a large history buffer. As such, I do have a lot of duplicate commands across multiple saved history files. Having 4 windows open all the time doesn't help with that overlapping history either.

function hsave(){
  history >> ~/work/projects/sweep/history-`date +'%Y%m%d%H%i%s'`$1.txt
function sg(){
  grep -ir $1 ~/work/projects/sweep

bash for loop


Because you need a loop when you're not in tcsh.

for fn in `cat filenames.txt`; do
    echo "the next file is $fn"
    cat $fn
# my one-liner
for f in `ls *JPG`; do echo $f; $f; done

Determine bash script's location from bash script


Sometimes, you need to know the current (full-path) directory of a bash script in order to launch another file relative to the bash script, instead of using global paths or the $PATH value.

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Replace all string matches from previous command in bash


$ !!:gs/replacethis/withthis/

gs = global replace

Works only with bash version 3 or greater:

bash-3.2$ bash --version 
GNU bash, version 3.2.57
$ echo oneone
$ !!:gs/one/two/    # Repeats last command; substitutes 'one' --> 'two'.