Bash Cheatsheet

I've gotten tired of googling the same things over and over again.

While loops

Note to self: If you find yourself doing this, you should probably stop and reevaluate why you're not using python. Also, this is obviously an infinite loop, and is probably not going to be especially helpful.

item=true
while [ $item = true ]; do echo 'bla'; done

SCP file between two remote hosts from your computer

This is useful if you have two aws instances, and want to transfer a file between them from your laptop.
scp -3 -i <pem file> user1@system_with_file:/file/to/xfer user2@system_that_needs_file:/file/to/xfer

Resource: https://superuser.com/questions/686394/scp-between-two-remote-hosts-from-my-third-pc

Create sudo user non-interactively

Skip the prompts that come with creating a user typically, and give them sudoers privileges. Replace *username* with the user you want to create.

adduser --disabled-password --gecos "" *username*
touch /etc/sudoers.d/10_*username*
echo '*username* ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/10_*username*

Resource: https://askubuntu.com/questions/94060/run-adduser-non-interactively

Run function as another user

export -f <function_name>
su <user to run function as> -c "bash -c <function_name>"

Exit-on-error mode

Put this at the top of your bash script: set -e.
If a command returns a nonzero status, the shell will exit.

Resource: https://unix.stackexchange.com/questions/97101/how-to-catch-an-error-in-a-linux-bash-script

Regexing with grep

This will get the version of ruby from rvm:
rvm list | head -n 1 |grep -Po '\-(.*?)\s' | tail -c +2
The output from that command that it is parsing will look something like this: ruby-2.5.1 [ x86_64 ]

It will return 2.5.1.

Resource: https://askubuntu.com/questions/89995/bash-remove-first-and-last-characters-from-a-string

See files that would be unzipped without unzipping

unzip -v <file>.zip>

Color output in less

Use less -r <file>

Code Style

Function declarations:

my_function(){

}

Variable declaration:

awesome_var='great'

Source filenames should be lowercase with underscores to separate words, i.e. the_best_script.sh

Resources:
https://google.github.io/styleguide/shell.xml#Variable_Names
https://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization

Find all bash_histories and send their contents to a file

find . -iname ".bash_history" -exec cat {} \; | tee ~/bash_histories.txt

Resource: https://stackoverflow.com/questions/864316/how-to-pipe-list-of-files-returned-by-find-command-to-cat-to-view-all-the-files

Global variables in functions

If you want to set something as a global variable and use it in a function, do the following:

export SOMETHING="variable"

great_function(){
    echo $SOMETHING
}

Parse an env file

export $(egrep -v '^#' .env | xargs)

The env file you want to parse should look something like this:

FOO='bar'
USERNAME='user'

Resource: https://gist.github.com/judy2k/7656bfe3b322d669ef75364a46327836

List all directories the current user has access to

find . -maxdepth 1 -type d -perm -u=rx

Find all bash_history files the current user can read

find . -maxdepth 1 -type d -perm -u=rx -print0 | xargs -0 -I{} find '{}' -readable -iname '.bash_history' 2>/dev/null

Find all .ssh directories that the current user has access to

Clean: find . -maxdepth 1 -type d -perm -u=rx -print0 | xargs -0 -I{} find '{}' -readable -type d -iname '.ssh' 2>/dev/null

Not quite as clean:

find . -maxdepth 1 -type d -perm -u=rx | xargs ls -lart 2>/dev/null |grep .ssh | grep "^.r..r..r"

Breaking this down:

find . -maxdepth 1 -type d -perm -u=rx - find all directories the current user has access to

| xargs ls -lart 2>/dev/null - send the output of the find command to ls -lart and suppress the Permission denied messages

|grep .ssh | grep "^.r..r..r" - output all files with ssh in the name with read permissions for all users

Send message to all users

echo "hi" | wall

Move file with rsync

rsync --partial --progress filename.txt user@ipaddress_or_hostname:~

Break up VM into multiple 1 GB files

Need to transfer a VM? Try this.
split -b 1000m vm.ova vm.ova.split

Bring it back together

cat vm.ova.splita* > vm.ova