Terminal Tips & Tricks
Published: 2023-03-12 05:37:31

Hello there. Today I'll be going over some handy tricks for navigating the terminal. As with my [last blog post](https://dev.to/topher2014/qmk-and-keyboards-3g2c) about keyboards and its software, QMK, this will not be an in depth technical post. A quick web search will provide endless pages of technical guides; this is meant to simply show some tricks that I've found useful and to inspire you to search out your own.

## Aliases
The first trick I'm going to cover is aliases. If you only take one thing away from this post, let it be this. Aside from using tab completion when entering commands, I can't think of an easier feature to implement that will save more time, reduce more typing, and increase workflow efficiency than aliases do.
Let's imagine a scenario. You're currently in a coding bootcamp, you're starting a new day of instruction at 8am, and you've just fired up a terminal window to work on your project. You need to get to your school folder, so you cd into Desktop, then cd into your school directory, then cd into the course directory, then cd into the project directory, then cd into the GitHub directory. Or, if you're really slick you just cd Desktop/School/Phase3/Project/GitHub, maybe even using tab completion to speed things up. But yeesh, that's still a lot of typing. Surely there's a better way? Well, there is!

```
[topher@TDesktop ~]$ Project 
[topher@TDesktop repo]$ pwd
/home/topher/Desktop/Flatiron/Phase3/Project/repo
[topher@TDesktop repo]$ 

```
 What is this black sorcery, you ask? Let's take a peek at my .bashrc file to find out.

```
[topher@TDesktop ~]$ cat .bashrc 

alias Project='cd ~/Desktop/Flatiron/Phase3/Project/repo'

```
As you can see, I've created an alias so that I can simply enter "Project" instead of "cd ~/Desktop/Flatiron/Phase3/Project/repo".
Let's take a more complete view of my .bashrc for some more examples.

```
### Command Aliases ###

# list 6 most recent files
alias lst='ls -lat | head -6'

# list all files, w/ color
alias ls='ls -la --color=auto'

# disk usage in human readable format, w/ max recursive depth of 1
alias du='du -hd1'

# tree w/ directories only
alias tree='tree -d'

# cd to last created directory
alias Ld='cd "$(\ls -1dt ./*/ | head -n 1)"'

# abbreviation for clear
alias c='clear'

# clear terminal buffer and list directory
alias cl='clear && ls'

### Flatiron Folder Aliases ###

alias Flatiron='cd ~/Desktop/Flatiron'
#alias Phase3='cd ~/Desktop/Flatiron/Phase3'
alias Project='cd ~/Desktop/Flatiron/Phase3/Project/repo'

### Functions ###

# Git clone clipboard and cd into newly created folder
function Git(){
    git clone $1
    cd  "$(\ls -1dt ./*/ | head -n 1)"
}

# Everything above, but open VSCode after
function GitCode(){
    git clone $1
    cd  "$(\ls -1dt ./*/ | head -n 1)"
    code .
}

# Everything above, but install npm before opening VSCode
function GCN(){
    git clone $1
    cd  "$(\ls -1dt ./*/ | head -n 1)"
    npm install
    code .
}
```
That last one clones the GitHub repo, cds into the new repo, installs npm, then opens VSCode, and all you have to do is prepend GCN to the GitHub URL. Pretty neat, huh? If you'd like to run the command without the alias, simply prepend a backslash to the command, like so...

```
[topher@TDesktop Temp]$ ls
total 8
drwxr-xr-x 2 topher topher 4096 Mar 11 19:45 .
drwxr-xr-x 7 topher topher 4096 Mar 11 19:45 ..
-rw-r--r-- 1 topher topher    0 Mar 11 19:45 ThisIsATempFile
[topher@TDesktop Temp]$ \ls
ThisIsATempFile
```
Where to put the aliases will depend on your OS and shell. I use Linux with Bash, so I could put my aliases is a number of files, including .profile, bash_profile, or .bashrc. I feel it's best to put them in .bashrc. Google your OS and shell to confirm where is best to place the commands is.

## Tree

Another useful tool while navigating the terminal is tree (which you can see I've made an alias for in my .bashrc). Most people are used to using a GUI file explorer in either a desktop environment or window manager, so it can get a bit confusing sometimes orienting yourself when you're using the terminal. Tree is a great tool to help do this. Let's see an example. Imagine we're trying to move a file to a different directory. We're starting in Temp/, trying to move Temp/Demo1/Demo3/file3 to Temp/Demo2...

```
total 16
drwxr-xr-x 4 topher topher 4096 Mar 11 20:20 .
drwxr-xr-x 9 topher topher 4096 Feb 25 19:32 ..
drwxr-xr-x 4 topher topher 4096 Mar 11 20:21 Demo1
drwxr-xr-x 2 topher topher 4096 Mar 11 20:21 Demo2
[topher@TDesktop Temp]$ ls Demo1/
total 16
drwxr-xr-x 4 topher topher 4096 Mar 11 20:21 .
drwxr-xr-x 4 topher topher 4096 Mar 11 20:20 ..
drwxr-xr-x 2 topher topher 4096 Mar 11 20:24 Demo3
drwxr-xr-x 2 topher topher 4096 Mar 11 20:24 Demo4
-rw-r--r-- 1 topher topher    0 Mar 11 20:20 file1
[topher@TDesktop Temp]$ ls Demo1/*
-rw-r--r-- 1 topher topher    0 Mar 11 20:20 Demo1/file1

Demo1/Demo3:
total 8
drwxr-xr-x 2 topher topher 4096 Mar 11 20:24 .
drwxr-xr-x 4 topher topher 4096 Mar 11 20:21 ..
-rw-r--r-- 1 topher topher    0 Mar 11 20:24 file3

Demo1/Demo4:
total 8
drwxr-xr-x 2 topher topher 4096 Mar 11 20:24 .
drwxr-xr-x 4 topher topher 4096 Mar 11 20:21 ..
-rw-r--r-- 1 topher topher    0 Mar 11 20:24 file4
[topher@TDesktop Temp]$ ls Demo2/
total 8
drwxr-xr-x 2 topher topher 4096 Mar 11 20:21 .
drwxr-xr-x 4 topher topher 4096 Mar 11 20:20 ..
-rw-r--r-- 1 topher topher    0 Mar 11 20:21 file2

```
Pretty difficult to visualize where in the file structure we are and are tying to get to, let alone to articulate. Let's see it again with tree (note the preceding backslash to negate the alias).

```
[topher@TDesktop Temp]$ \tree
.
├── Demo1
│   ├── Demo3
│   │   └── file3
│   ├── Demo4
│   │   └── file4
│   └── file1
└── Demo2
    └── file2

5 directories, 4 files

```
Much easier to keep track of where we are and where everything is. It's also much easier to explain our file structure with this as a visual. Let's move that file and run tree again.

```
[topher@TDesktop Temp]$ mv Demo1/Demo3/file3 Demo2/
[topher@TDesktop Temp]$ \tree
.
├── Demo1
│   ├── Demo3
│   ├── Demo4
│   │   └── file4
│   └── file1
└── Demo2
    ├── file2
    └── file3

5 directories, 4 files

```
Cool beans, huh?!
Tree can also be a useful substitute or companion to pwd.

```
[topher@TDesktop Temp]$ pwd
/home/topher/Desktop/Temp
[topher@TDesktop Temp]$ tree -L 1 ..
..
├── Documents
├── Downloads
├── Flatiron
├── Pictures
├── Purgatory
├── QMK
└── Temp

8 directories

```
Take notice that since this time I did not prepend tree with a backslash, tree is using my alias that causes it to only display folders, not files. The proceeding "-L 1" is telling tree go one level deep, while ".." is telling tree to run on the previous folder, Desktop.
Pwd and ls are essential tools, but tree can be really helpful to give a fuller picture.

## Head and Tail

You may have noticed that I used head in my .bashrc in my ls alias. This is one of my favorite command combinations. Imagine another scenario... Let's say you're online sailing the high seas, matey. You're using your favorite torrent or Usenet client (if you're a fellow buccaneer and haven't tried Usenet yet, I highly recommend it). You've got a couple of new files in your Downloads folder and would like to transfer them (you should have this automated, but just humor me). Lets use the ol' ls command to check out the Downloads folder...

```
[topher@TDesktop Downloads]$ ls
total 8468004
drwxr-xr-x 14 topher topher      20480 Mar 11 18:10  .
drwxr-xr-x  9 topher topher       4096 Feb 25 19:32  ..
-rw-r--r--  1 topher topher 1954545664 Oct 30  2021  2021-10-30-raspios-bullseye-armhf-lite.img
-rw-r--r--  1 topher topher  485827056 Dec 17  2021  2021-10-30-raspios-bullseye-armhf-lite.zip
-rw-r--r--  1 topher topher     205388 Feb  7 18:11  3309965714262467221.jpg
-rw-r--r--  1 topher topher     112904 Jul 28  2022  4768872250852101121.jpg
-rw-r--r--  1 topher topher      18146 Dec 23 12:25  52116190237_64d77291d7_o.jpg
drwxrwxr-x  2 topher topher       4096 Feb 13  2022  578d2295a13a246c9a061143ced0ab22-f4509832c1b5acbe4d2d09c9c0560f3ba4ff33e6
-rw-rw-r--  1 topher topher       2240 Feb 13  2022  578d2295a13a246c9a061143ced0ab22-f4509832c1b5acbe4d2d09c9c0560f3ba4ff33e6.zip
-rw-r--r--  1 topher topher     145534 Jul 28  2022  6126558894253767245.jpg
-rw-r--r--  1 topher topher     496128 Aug 23  2022  alsa-lib-1.2.7.1-1-x86_64.pkg.tar.zst
-rw-r--r--  1 topher topher     496285 Aug 23  2022  alsa-lib-1.2.7.2-1-x86_64.pkg.tar.zst
-rw-r--r--  1 topher topher      61195 Aug 23  2022  alsa-ucm-conf-1.2.7.1-1-any.pkg.tar.zst
-rw-r--r--  1 topher topher      62057 Aug 23  2022  alsa-ucm-conf-1.2.7.2-1-any.pkg.tar.zst
-rw-r--r--  1 topher topher  846540800 Mar  4  2022  archlinux-2022.03.01-x86_64.iso
-rw-r--r--  1 topher topher      48034 Mar  1  2022  archlinux-2022.03.01-x86_64.iso.torrent
-rw-r--r--  1 topher topher      40957 Jan 26 11:14  August_Burns_Red_Rescue_and_Restore_WEB_2013_ENTiTLED_iNT.nzb
-rw-r--r--  1 topher topher    2204143 Jul 14  2022  b30953_397a700285664bcb81e53bd47175c744~mv2.png
-rw-r--r--  1 topher topher      29315 Apr 14  2022  BackupPasswords
-rw-r--r--  1 topher topher        159 Dec 13  2021  bash_profile
drwxr-xr-x  4 topher topher       4096 Nov 22 01:52  BillySkydive
drwxr-xr-x  2 topher topher       4096 Jul  8  2022  bin
-rw-r--r--  1 topher topher    3135669 Feb 17 09:05  Challenge-1-Bank-of-Flatiron-021023.zip
-rw-r--r--  1 topher topher       6440 Nov  8 20:49 'ch.protonvpn.net.udp(1).ovpn'
-rw-r--r--  1 topher topher       6445 Nov  8 20:49  ch.protonvpn.net.udp.ovpn
-rw-r--r--  1 topher topher      35375 Mar  8 14:42  ClockworkOrange.jpg
-rw-r--r--  1 topher topher   14954416 Mar  8 15:17  code-1.56.2-3-x86_64.pkg.tar.zst
-rw-r--r--  1 topher topher     834804 Jul  8  2022  code-challenge.bundle
-rw-r--r--  1 topher topher      27754 Mar 13  2022  download
-rw-r--r--  1 topher topher     121586 Apr 14  2022  Dropbox.zip
-rw-rw-r--  1 topher topher       6148 Feb 15  2022  DS_Store
-rw-r--r--  1 topher topher  143534080 Apr 12  2022  emby-server-synology7_4.6.7.0_x86_64.spk
-rw-r--r--  1 topher topher    4563318 Aug 15  2022  embyserver.txt
-rw-r--r--  1 topher topher  155330168 Aug 16  2022  emby-theater-flatpak_3.0.16_x86_64.flatpak
-rw-r--r--  1 topher topher  152959333 Aug 16  2022 'emby-theater-rpm_3.0.16_x86_64(1).rpm'
-rw-r--r--  1 topher topher  152959333 Aug 15  2022  emby-theater-rpm_3.0.16_x86_64.rpm
-rw-r--r--  1 topher topher     248611 Jan 14 14:37  epic_handshake_meme-e1534136962951.png
-rw-r--r--  1 topher topher       8467 Jul 10  2022 'es.protonvpn.net.udp(1).ovpn'
-rw-r--r--  1 topher topher       8447 Jul 10  2022 'es.protonvpn.net.udp(2).ovpn'
-rw-r--r--  1 topher topher       8497 Jul 10  2022  es.protonvpn.net.udp.ovpn
-rw-r--r--  1 topher topher       8769 Dec 21 11:14  example-code-challenge-2021-02-24.zip
drwxr-xr-x  3 topher topher       4096 Mar 10 18:46 'Experimental BDN9 Streamdeck'
-rw-r--r--  1 topher topher       8495 Mar 10 18:44 'Experimental BDN9 Streamdeck-20230311T024437Z-001.zip'
-rw-r--r--  1 topher topher     118590 Mar 10 21:20  ffdlSQBsKMtpYFd8h9IMAHbqE9c9GWrAZoa6m8Yb_GA.webp
-rw-r--r--  1 topher topher       1956 Mar 12  2022  firewallConfig.rsc
```
Yikes. That's a lot of output, and that's only maybe 1/4 of my Downloads folder. That's pretty unsightly, not to mention some terminals won't have the buffer space to let you look through everything. Let's run ls again, but this time let's use head to only show a few files. I'm also going to add "-t" so that files are listed by modified date.

```
[topher@TDesktop Downloads]$ ls -t | head -4
total 8468004
drwxr-xr-x 14 topher topher      20480 Mar 11 18:10 .
-rw-r--r--  1 topher topher       9534 Mar 11 18:10 images.jpeg
-rw-r--r--  1 topher topher    1167107 Mar 10 22:08 Screenshot_20230310-220720~2.png

```
Aaaah, much better. You can see I've run ls with the -t flag. The "|" is a pipe, which I'll cover in the next and final section. Finally, we come to "head -4". In this particular use, head is shortening the output to four lines: the total, the "." representing the current directory, and then our two most recent files.
Tail does the same thing, just for the final output instead of the first.

```
[topher@TDesktop Downloads]$ ls -t | tail -4
-rw-rw-r--  1 topher topher  100341760 Dec 23  2021 PlexMediaServer-1.25.2.5319-c43dc0277-x86_64_DSM7.spk
-rw-r--r--  1 topher topher  485827056 Dec 17  2021 2021-10-30-raspios-bullseye-armhf-lite.zip
-rw-r--r--  1 topher topher        159 Dec 13  2021 bash_profile
-rw-r--r--  1 topher topher 1954545664 Oct 30  2021 2021-10-30-raspios-bullseye-armhf-lite.img

```
Head and tail can be a really handy tools when you're working with a lot files/output.

## Pipe

As promised, this final section will cover pipe. I don't want to get too in the weeds with this one, because you absolutely can, but the important thing to know about pipes is that they 
redirect output to another destination. Here's a simple example using cat and sort...

```
[topher@TDesktop Demo1]$ cat file1 
g
o
f
u
c
k
y
o
u
r
s
e
l
f
,
s
a
m
:)
[topher@TDesktop Demo1]$ cat file1 | sort
,
:)
a
c
e
f
f
g
k
l
m
o
o
r
s
s
u
u
y

```
As you can see, cat output the contents of file1 and was "piped" to sort, which sorted the contents. This may not seem super impressive, but it's very useful when you're chaining commands together or using scripts.

## Final Thought
As I said, this post was not meant to be a super exhaustive technical read. The main point I want to get across is that if you find yourself wishing something were simpler or more automated while using the terminal, chances are you can achieve that. Hopefully I've sparked your imagination and you'll go search out some awesome terminal tricks of your own. And if you have any that you find useful, leave them in the comments!