Here is a collection of super useful shell scripts and bash aliases that helped me a lot during the time to boost my productivity.


Terminal, command line, console, shell, bash

Honestly I'm always mixing up these things. I usually call the terminal as a command line or console. Also I just say simply shell or bash based on the current context without worrying to much about the actual differences. That's not a major issue, because - I believe - most of the dev community is doing the exact same thing, but let's clear things up a little bit just for the sake of this article. ☺️

A terminal is something that you can sit down at. Nowadays, you can simply start the built-in Terminal application both on macOS and linux, so it's more like an app, that emulates a console. A text-only graphical user interface in a window. 💻

The console is basically an interface that contains the controls for a machine. It's a special kind of terminal, but sometimes it means the keyboard and monitor that's physically attached to a computer. Gaming consoles, anyone? 🎮

The command line is the space to the right of the prompt. WHUT? A prompt is  the text representation of where the user is currently. The cursor. In other words it's the place where you can enter commands and you press return to execute them. ⌨️

Shell is a program which processes the input commands and returns the output. It's an operating system wide thing, for interacting with the low level kernel. It's an easy way of sending commands to the kernel. It's the primary interface that users see if they log in, and it's primary purpose is to start other programs. 🐚

There are many different unix shell alternatives and implementations, but they usually share a common syntax. Bash is definitely the most popular one, but there are some others like ash, dash, ksh or zsh. Pretty much any unix-like system has a bourne-style shell installed as /bin/sh, which is usually defaults to bash. 👊


Useful shell commands for beginners

If you know nothing about shell commands, you should start practicing with some relatively simple tasks, like changing directories, creating, moving and removing them, working with files and some other little neat commands that can save you time. In the beginning it will be still faster just to use a UI application to solve those tasks, but on a long term you can save lots of time by learning bash. Please do so! ⏳

Here are my favorite core commands that I can't live without: 😅


# man - format and display the on-line manual pages
man [command] #if you are lost, just RTFM!

# whoami -- display effective user id
whoami #prints the current user's name

# pwd -- return working directory name
pwd #prints the current directory

# ls -- list directory contents
ls #lists the contents of the current directory
ls -la #lists all the files in a longer format

# cd -- change directory
cd [directory] #moves to a given directory like "/Users/tib/"
cd ~ #moves to home directory
cd .. #moves up a directory

#mkdir -- make directories
mkdir [directory] #creates a directory
mkdir -p [dir1/dir2/dir3] #creates the whole directory structure

# cp -- copy files
cp [source] [destination] #copies the source into the destination

# mv -- move files
mv [source] [destination] #moves the source into the destination

# ln -- make links
ln [source] [destination] #creates a link from the source to the destination

# rm -- remove directory entries
rm [file] #removes the given file
rm -r [directory] #removes the given file

# chmod -- change file modes or Access Control Lists
chmod 644 [file] #changes file permissions
chmod -r 644 [directory] #same, but recursively

# chown -- change file owner and group
chown tib:staff [file] #changes owner & group
chown -r tib:staff [directory] #same but recursively

# cat -- concatenate and print files
cat [file] #prints out the contents of a file

# wc -- word, line, character, and byte count
wc -l [file] #prints out the line count of a file
wc -c [file] #prints out the byte count of a file
wc -w [file] #prints out the word count of a file

# grep -- file pattern searcher
ls -la | grep [term] #search for a folder name (term) in a directory list
cat test.txt | grep [term] #search for a term in a file

# echo -- write arguments to the standard output
echo "[text]" #prints out text

# which -- locate a program file in the user's path
which [command] #looks for a command, if found prints location

# touch -- change file access and modification times
touch [file] #creates the file or updates it's appropriate times

# nano - Nano's ANOther editor, an enhanced free Pico clone
nano [file] #opens & creates a file for editing

# sips -- scriptable image processing system.
sips -Z [size] [image] #scale an image to a max size

# alias - creates an alias
alias la='ls -la' #from now you can use la as a shortcut

# export exports a variable
export [name]=[value] #later on you can assess it by using $name

That's it for the first round. I know it can be a little bit too much at the first sight, but trust me it's way more easy than you think. Just start playing around with these commands and eventually you're going to fell in love with them. ❤️

Quick note:
You can also put your commands into files called shell scripts, plus shell also supports creating functions (like in a real programming language) and more.

Working with remote servers

Usually in a working environment, you don't just work on your local machine, but you have to connect to remote servers, use git repositories, transfer files, etc. In this section I'm going to give you a brief overview of how these things can work by using only the command line (for me it's usually faster than using an app with a GUI). 🤪

# curl - transfer a URL
curl 
    -i \                                 # interactive = logs
    -X [method] \                        # HTTP method: GET, POST, etc.
    -H "Content-Type: aplication/json" \ # add header field
    -H "Accept: aplication/json" \       # add header field
    -d '{"Hello": "world!"}' \           # data (HTTP body)
    http://example.com/api/endpoint      # endpoint

# ssh -- OpenSSH SSH client (remote login program)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # genertes a new key
ssh [server] #logs in to a remote server

# sftp -- secure file transfer program
sftp [server] #logs in to the server (use help for more)

# git - the stupid content tracker 
git init
git add .
git commit -m [message]
git status
git remote add origin git@github.com:[org]/[repo].git
git push --set-upstream origin master
git pull
git log
# ... and many more...

You can split long commands into multiple lines by using the \ character. Also if you are using ssh it's a good practice to create config files for servers, so the whole login process will be a lot more easy, you don't have to specify user name, port and many more, you can simply use an alias for a server.

# .ssh/config file 
Host            example
HostName        example.com
Port            22
User            tib
IdentityFile    ~/.ssh/example.com.private.key
IdentitiesOnly  yes
UseKeychain     yes
AddKeysToAgent  yes

From now on you can use ssh example without additional parameters. 👍

Customizing your bash

In order to customize your environment you have to work with the built-in variables. This means that you have to export new values for specific ones. If you do so, it'll only take effect in your current terminal session, no permanent changes at all. 🙅‍♂️

#overrides the current editor
export EDITOR=nano
# prints out the EDITOR variable
echo $EDITOR

# add new folder to the path variable
export PATH="/usr/local/sbin:$PATH"
# path
echo $PATH

# set a custom prompt
export PS1="\u@\w\[\033[32m\]\$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/')\[\033[00m\]: "
# prints the PS1 variable
echo $PS1

# home folder (you shouldn't touch this)
echo $HOME

If you put these lines to a file called .bash_profile under your home directory, they'll be permanently added to all of your terminal sessions.


My favorite aliases

I've created some useful aliases which I use quite frequently. My personal favorites are x, gs, p, spm.x but of course you can change these names for yourself.

# some of my git aliases (I've got around a hundred)
alias git.log="git log"
alias git.log.list="git log --pretty=oneline"
alias git.log.last="git log -1"
alias git.log.last.id="git rev-parse HEAD"
alias git.log.search="git log --all --grep"
alias git.log.graph="git log --graph --oneline --decorate --all"
alias git.log.files="git diff-tree --no-commit-id --name-only -r"
alias git.contributors="git shortlog -es | cut -f2 | sed 's/^/- /'"
alias git.origin.url="git config --get remote.origin.url"
alias git.commit.all="git add -A && git commit -a -m"
function git.push.all() { git.commit.all "$1"; git push; }
function git.clone.github() { git clone https://github.com/"$1".git; }
alias gs='git status'
alias p="git.push.all"
alias c="git.commit.all"
alias gl='git.log -1'
alias gp='git pull'


# prints public ip address 
alias myip='curl ip.appspot.com' 
# prints local ip address
alias ip='ipconfig getifaddr en0' 
# checks for network connection by pinging google
alias png="ping 8.8.8.8"
# flush dns cache
alias flushdns="sudo dscacheutil -flushcache;sudo killall -HUP mDNSResponder" 


# Swif / iOS / Xcode related stuff
alias xcode.normal='sudo xcode-select -s /Applications/Xcode.app/Contents/Developer/'
alias xcode.beta='sudo xcode-select -s /Applications/Xcode-beta.app/Contents/Developer/'
alias swift.dev='export PATH=/Library/Developer/Toolchains/`ls /Library/Developer/Toolchains/|grep DEV`/usr/bin:"${PATH}"'

alias pod.update='pod update --no-integrate'
alias pod.install='pod install --no-integrate'
alias pod.lint='pod lib lint *.podspec'
alias pod.push.corekit='pod repo push corekit *.podspec'

alias symbolicate="DEVELOPER_DIR=$(xcode-select -p) /Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash"
alias ios="open /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone\ Simulator.app"
alias ederived='rm -rf ~/Library/Developer/Xcode/DerivedData/*'
alias getfwinfo="xcrun -sdk iphoneos lipo -info"
alias x='matches=("xcworkspace" "xcodeproj" "playground"); for i in "${matches[@]}"; do if [ -d *.${i} ]; then open -a Xcode *.${i}; break; fi; done'
alias pg='open -a Xcode ~/Library/Mobile\ Documents/iCloud\~com\~apple\~Playgrounds/Documents/Empty.playground'
alias codesigndoc='bash -l -c "$(curl -sfL https://raw.githubusercontent.com/bitrise-tools/codesigndoc/master/_scripts/install_wrap-xcode.sh)"'

alias spm.init.executable='swift package init --type=executable'
alias spm.init.library='swift package init --type=library'
alias spm.update='swift package update'
alias spm.fuck.it='rm -rf .build/ && rm -rf Package.resolved && rm -rf *.xcodeproj'
alias spm.run='swift run'
alias spm.xcode='swift package generate-xcodeproj'
alias spm.x='spm.xcode && x'

alias docker.swift='docker build -t my-swift-image . && docker run --rm my-swift-image'

Writing about shell scripts & bash turned out to be really hard, because I had to pick a little slice of all the things that came into my mind. It's a huge topic, even just using curl could be a standalone blog post... so you've got the scope. 😉

If you enjoyed this article, please follow me & subscribe!


External sources