Bash Tips - Tip 1
Recently, I was pairing with a developer on a client’s team. He was stuck and couldn’t figure out how to fix the problem. I had a look and guided him through a series of bash and other shell commands until we found the solution. After thanking me — he had been at it for hours — he asked me “How do you know all of this?” I could tell from his tone that what he was really asking was “From what book did you learn all of this?” Thing is, I didn’t learn “all of this” from a book. Having been at it since 1997, I learned it through good old fashioned trial and error. That and being exposed to new tools.
That conversation sparked the idea that I should share this knowledge through a series of posts. My goal is to make it easily accessible for all who could use this information. If you have pressing needs, let me know, and I might cover that tip next.
For now, here’s tip number one:
Aliases
An alias
is similar in the real world as it is in a shell. So if we look at the ls
command, which lists all of the files in the current directory, we’ll see something like this.
$ ls -a
. .. .bash_profile .git .tmux.conf .vimrc README.md alacritty.yml
What if we want this list to be vertical and show file sizes in human-readable format? The command would be:
$ ls -alh
total 48
drwxr-xr-x 8 david staff 272B Jan 11 09:41 .
drwxr-xr-x+ 117 david staff 3.9K Feb 22 11:27 ..
-rw-r--r-- 1 david staff 2.2K Nov 30 17:00 .bash_profile
drwxr-xr-x 14 david staff 476B Sep 23 13:09 .git
-rw-r--r-- 1 david staff 1.2K Jun 28 2016 .tmux.conf
-rw-r--r-- 1 david staff 2.6K Jan 26 01:04 .vimrc
-rw-r--r-- 1 david staff 79B Oct 12 2014 README.md
-rw-r--r-- 1 david staff 7.3K Jan 11 09:49 alacritty.yml
And if we want to be able to access this quickly, we can set it up as an alias.
$ alias lh='ls -alh'
Now, anytime we type lh
into our shell, it will give us the same output.
$ lh
total 48
drwxr-xr-x 8 david staff 272B Jan 11 09:41 .
drwxr-xr-x+ 117 david staff 3.9K Feb 22 11:27 ..
-rw-r--r-- 1 david staff 2.2K Nov 30 17:00 .bash_profile
drwxr-xr-x 14 david staff 476B Sep 23 13:09 .git
-rw-r--r-- 1 david staff 1.2K Jun 28 2016 .tmux.conf
-rw-r--r-- 1 david staff 2.6K Jan 26 01:04 .vimrc
-rw-r--r-- 1 david staff 79B Oct 12 2014 README.md
-rw-r--r-- 1 david staff 7.3K Jan 11 09:49 alacritty.yml
However, if we want this alias
to persist, we need to store it somewhere. When using bash
, there’s a config file we can reference. For nix systems, it should be ~/.bashrc
, and for Mac OS X, ~/.bash_profile
. This file is used when the shell starts to set up its environment. This file will most likely already exist, so let’s add our new alias.
# Setup Alias for lh
alias lh='ls -alh'
This is in the config for bash
, but our current shell has the old configuration loaded. To load the new config changes, we need to source
this file.
$ source ~/.bash_profile
Now, our current shell and any future ones will have our new alias
available.
SSHing into Different Machines
If you’ve ever used an Amazon EC2 instance, set up a local Virtual Machine (VM), or accessed another machine across the internet, you might have used ssh
, which stands for Secure SHell. A typical connection might look like this:
ssh ssh.someserver.com -l myusername -p 9000 -i "~/.ssh/my_keyfile.pem"
Since I don’t want to have to remember this all the time, what are my options?
alias
I could create an alias for this connection:
# include in ~/.bash_profile or ~/.bashrc
alias ssh-someserver='ssh ssh.someserver.com -l myusername -p 9000 -i "~/.ssh/my_keyfile.pem"'
This works, but the list could grow quite large if we have numerous servers we need to connect to.
And… there is a built-in solution to handle this with ssh
.
ssh config
By default, ssh
uses the path ~/.ssh/config
as a place to look up information if it is available. This means we can add the connection information to this server and access it with ssh
.
# include in ~/.ssh/config
Host someserver
Hostname ssh.someserver.com
Port 9000
User myusername
IdentityFile "~/.ssh/my_keyfile.pem"
Now, all we have to do is use the Host
name to ssh
into this machine.
ssh someserver
And all we have to remember now is which server we want to connect to and type its name after ssh
. The added benefit is this config file works with other ssh
tools like scp
.
Securely Copy Files
The scp
command works similarly to the cp
command, but can access other machines via ssh
.
scp someserver:~/project/README.md ~/Downloads/project-README.md
Here, we’re going to copy the README.md
file from the project
folder on the someserver
box and put it into our local Downloads
folder, but rename it to project-README.md
since we want to know which readme this is for.
Stopping a Local Process
There are times when we might leave our ssh
session open and, after a period of time or if the internet connection is lost, the ssh
session will become unresponsive. If we weren’t running an active task remotely, the ssh
session isn’t really “hung,” but rather, it’s trying to re-establish a connection. This can be frustrating if we know the connection won’t go through as that bash
session will not be usable.
The quickest way, that I have found, to get control of that window back is the following:
- Start a new Terminal/bash window.
- Run
ps aux | grep ssh
. - Find the
pid
of the “hung”ssh
connection. - Run
kill <pid>
.
The goal here is to find the ssh
session that most likely will fail anyway and tell it to exit. This is what it would look like:
$ ps xao user,pid,comm | grep ssh
david 16510 vim .ssh/config
david 21462 /usr/bin/ssh-agent -l
david 16738 grep --color -E ssh
david 16733 ssh my_remote_server
$ kill 16733
Typically, I use ps aux
, but for formatting reasons on this post, I thought it would be helpful to only show the username (user) of the active process, the process id (pid) — to determine what to pass to the kill
command — and the command (comm) itself.
Running the kill
command most likely won’t show anything in the second shell we are using, but in the first shell, that ssh
connection will end up looking something like this:
myusername@someserver:~$ Killed by signal 15.
$
A lot of developers just use the kill -9
command. This specifies the signal to send to the program. The list of kill signals can be found on the kill
man page.
Some of the more commonly used signals:
1 HUP (hang up)
2 INT (interrupt)
3 QUIT (quit)
6 ABRT (abort)
9 KILL (non-catchable, non-ignorable kill)
14 ALRM (alarm clock)
15 TERM (software termination signal)
So if we had used that instead, we would have seen this in the first shell.
myusername@someserver:~$ Killed: 9
$
Questions?
If you need clarification on this tip, just ask in the comments below. I’d love to help! And remember, if you have questions about bash and other shell commands, let me know, and I might cover that topic next.
Want to be alerted when we publish future blogs? Sign up for our newsletter!