Table of Contents
The shell is the program that allows a user or another program to interface with the operating system’s internal services and system programs. In a Unix-based system (i.e. any Linux Distribution (or distro for short), mac OS, OpenBSD, etc.) the base shell is normally accessed through the terminal; in any NT-based operating system (anything Windows) the base shell is access through the command line (cmd). The graphical user interface (GUI) of an operating system could technically be considered a shell as well, but does not easily allow for the automation repetitive tasks, and thus is a little useless in power computing or harnessing the full potential of your computer. If you are interested in learning more about different types of GUIs, this article is a good read and can help you prettify your distro! But if you are interested in tackling the the terminal and become proficient in your shell abilities, this is definitely a good place to start.
Why should I use the shell?
There are a number of different reasons why using the shell is advantageous in power computing, especially when creating specialized systems centered around your own custom software or setup. If you ask the average Linux user why bothering with the terminal is important, you’ll likely hear some of these reasons:
- It’s faster
- It’s more powerful (i.e. batch operations, such as deleting multiple files with a specific pattern, etc.)
- Facilitates automation (i.e. scheduled tasks, scripting, etc.)
- Easy remote access
- You look like a cool hacker 😎
While all of these reasons are valid and should definitely be pursued, using the shell in a research environment requires a more in-depth exposure. Although this may sound intimidating at first, with a little time and Googling, a mastery of the shell will allow you to:
- Understand the inner workings of most operating systems
- Design intelligent systems
- Open horizons into hardware hacking/integration
- Sound like a cool hacker 😎💻
Choose your weapon
Fast-forwarding through a dry and nerdy explanation of who made what shell and why that is super exciting, we will take a look at the current popular shell programs that exist at the time of this writing. What? You can change your shell? Why would I even want to do that when what I use right now works perfectly well? All very valid questions. Maybe I can convince you with two pictures:
Here we have the default shell in Ubuntu 20.04:
This is using the vanilla (i.e, not plugins added or preferences changed) Bourne Again SHell (bash).
Next up we have the shell configuration I personally use (still in Ubuntu 20.04):
This is using the Z Shell (zsh, pronounced ‘zeesh’) with the Powerlevel10k theme on Oh My Zsh, using NerdFonts for the fun glyphs. You’ll also notice an inclusion of a timestamp of the last command entered and a status icon to indicate the return code of the previous command (if everything is okay, or 0, the default glyph is the green checkmark). If these things seem more like distractions rather than enhancements or you are simply content with the basic setup, feel free to skip to the next session.
So far this just looks like a theming difference, no? Well, its this theming that allows you to enjoy some pretty powerful tools that you wouldn’t get otherwise. For example, lets do a little versus session just between vanilla bash and the my zsh setup to get an idea of some basic perks of modding your shell:
In vanilla bash, it is hard to see when you are in a git repository as opposed to a normal directory:
This doesn’t seem like too bad of an issue, right? Wrong. Anyone who has worked with git repos will know that when you make accidental changes to files inside of a repository, it can be downright terrible to try and revert the files their previous state.
Lets compare this to the zsh setup from above with the same directory’s prompt:
Not only is there a little section with an icon that shows a branch and the GitHub icon, it also gives an indicator on how many uncommitted files exist without you ever needing to enter
git status just to see if anything has changed.
This seems more like a nit-picky difference to me, but I think it is worth including just the same. Python environments are neat containers that allow you to install project-specific libraries within its own confined space. Knowing when you are in one of these environments is critical to your project seeing as you could install a library on the general system unsuccessfully and end up ruining your whole operating system as a consequence (true story).
In bash, the indicator for the pyenv is prepended to the normal prompt you get in any other directory. Though this might not be true for everyone, it was certainly easy enough for me to miss:
Although it is not too big of a difference, my current zsh theme takes a different approach in placing the name of the environment you are in:
By having the name of the pyenv in a different location, the eye is drawn to information which takes up normally empty space in the default prompt, making the fact that you are in a pyenv a little more noticable. Like I said, nit-picky, but helpful nonetheless.
In any basic shell, you can use the
history command to view a buffer of all commands entered inside the shell environment. Alternatively, you can also use the up arrow to scroll through the last entered commands. For many people, this seems to work well enough, after all, it the default behavior on bash:
Zsh’s control of searching through command history is a little more intelligent. Instead of of just being able to scroll through command history, you can also scroll through a filtered history chronologically. All that is different is that you need to type in the desired pattern before hitting the up arrow:
Whether this is fascinating to you or not, these are just a few perks that come from a very specific setup. Thankfully, the opensource is vast and very creative, which means that even if these perks don’t tickle your fancy, odds are there is something that will! Below is a table of common shells that are in use today, all with their varying pros and cons. If you are feeling adventurous enough, install a few of them on your machine and see which one feels the best!
|Bourne Shell (sh)||The evolution of the original shell developed by Thompson (one of the authors of the C programming language). This is the most basic shell you will be greeted with when remoting into a Linux-enabled, embedded machine. Elements of this shell’s syntax are found in most others.||N/A|
|Bourne Again SHell (bash)||Shell that is used in Debian-based distros, which seems to be an enhancement of the Bourne Shell as the name denotes. This shell comes default on Ubuntu||https://www.gnu.org/software/bash/|
|Debian Almquist SHell (dash)||Shell that is default in the Debian Linux distro. Similar to sh with few syntactical changes||https://www.in-ulm.de/~mascheck/various/ash/|
|TENEX C SHell (tcsh)||Shell that is sh-like which is the default shell program on all BSD-based systems.||https://www.tcsh.org/|
|Z SHell (zsh)||Enhanced version of Bourne Again Shell with a wide variety of plugins, customization including command specific history.||https://www.zsh.org/|
|Korn SHell (ksh)||Middle of the road between the tcsh predecessor (csh) and sh.||http://www.kornshell.com/|
|Friendly Interactive SHell (fish)||Bash-based shell focused on user friendliness, command suggestions, and command specific auto-completion.||https://fishshell.com/|
NOTE: In most of the pages for Linux Magic, we will be using the bash/zsh/fish/dash/sh syntax, seeing as most of these shells are the most popular and all have nearly identical syntax.
At first glance, interfacing with the shell may seem intimidating. A blank screen with only text can be daunting for many, but this should soon subside once you realize that you are basically in the folder explorer of your distro. To confirm where you are at, type in
pwd (short for print working directory). Hitting
Enter after typing the command in will return the path of your directory, or the list of parent folders for the folder you are currently in. For example, if I were using the file browser and I went to the top-most or root (/) directory, and then went to look for my home folder, the list of successive folders from root to the home folder in the browser could look something like this:
Here you can see that the
home folder is expanded and my user folder
kchristm is visible. When in the terminal if I type in
pwd right after opening the terminal, the folder I should be in by default is my home directory. The output of my command is:
❯ pwd /home/kchristm
Pretty straightforward, no?
Checking folder contents
But simply knowing where you are in the file system isn’t super useful all by itself. After all, directories (or folders) are just containers. It’s what’s in them that is more interesting to us. To see the contents of a directory, we will type in
ls which will list the folder’s contents:
❯ ls 7_Segment_Array_Display_Clock.ino formatTime.py powerlevel10k apps hillcrest_elementary.csv Public Desktop lindon_pioneer_ln.csv seven_seg.png dev Music snap Documents oak_hills.csv Templates Downloads orem_firehouse.csv thonny-latest.sh EAGLE out.txt Videos edgemont.csv pico env Pictures
This is where the shell starts to become interesting.
ls (much like
pwd) is a command, and each command has flags or special options that come after a hyphen which allow for some special functionalities. Lets go ahead and use the
l flag after
ls and see what it does:
❯ ls -l total 180784 -rw-rw-r-- 1 kchristm kchristm 20499 Jun 2 13:52 7_Segment_Array_Display_Clock.ino drwxrwxr-x 3 kchristm kchristm 4096 May 28 13:08 apps drwxr-xr-x 2 kchristm kchristm 4096 May 28 13:08 Desktop drwxrwxr-x 8 kchristm kchristm 4096 May 28 10:23 dev drwxr-xr-x 4 kchristm kchristm 4096 Jun 2 11:22 Documents drwxr-xr-x 4 kchristm kchristm 4096 May 26 08:37 Downloads drwxrwxr-x 10 kchristm kchristm 4096 May 26 08:58 EAGLE -rw-rw-r-- 1 kchristm kchristm 28478118 May 25 13:21 edgemont.csv drwxrwxr-x 3 kchristm kchristm 4096 May 18 12:16 env -rw-rw-r-- 1 kchristm kchristm 518 May 25 13:20 formatTime.py -rw-rw-r-- 1 kchristm kchristm 35316584 May 25 13:15 hillcrest_elementary.csv -rw-rw-r-- 1 kchristm kchristm 33929904 May 25 13:15 lindon_pioneer_ln.csv drwxr-xr-x 2 kchristm kchristm 4096 May 17 16:23 Music -rw-rw-r-- 1 kchristm kchristm 29502077 May 25 13:16 oak_hills.csv -rw-rw-r-- 1 kchristm kchristm 31997247 May 25 13:16 orem_firehouse.csv -rw-rw-r-- 1 kchristm kchristm 25575881 Mar 9 23:22 out.txt drwxrwxr-x 4 kchristm kchristm 4096 May 28 12:55 pico drwxr-xr-x 3 kchristm kchristm 4096 May 25 12:53 Pictures drwxr-xr-x 6 kchristm kchristm 4096 May 17 18:01 powerlevel10k drwxr-xr-x 2 kchristm kchristm 4096 May 17 16:23 Public -rw-rw-r-- 1 kchristm kchristm 214841 May 26 09:00 seven_seg.png drwxr-xr-x 4 kchristm kchristm 4096 May 25 15:50 snap drwxr-xr-x 2 kchristm kchristm 4096 May 17 16:23 Templates -rwxrwxr-x 1 kchristm kchristm 763 May 23 02:22 thonny-latest.sh drwxr-xr-x 2 kchristm kchristm 4096 May 17 16:23 Videos
As you can see, I have practically the same output. It’s still just the contents of my working directory. But as you have probably noticed, they have been displayed in a list. Other interesting bits of information such as the permissions of each file or folder, to whom its belongs and their corresponding group, and other metadata is displayed as well.
Flags can also be compounded together. For example, in
a flag shows all the files in a directory (including the hidden files). Now when I type in
ls -la , I will see all the files in a list format:
❯ ls -la total 181104 drwxr-xr-x 31 kchristm kchristm 4096 Jun 2 16:02 . drwxr-xr-x 4 root root 4096 May 17 16:14 .. -rw-rw-r-- 1 kchristm kchristm 20499 Jun 2 13:52 7_Segment_Array_Display_Clock.ino drwxrwxr-x 3 kchristm kchristm 4096 May 28 13:08 apps -rw------- 1 kchristm kchristm 314 Jun 2 11:22 .bash_history -rw-r--r-- 1 kchristm kchristm 220 May 17 16:14 .bash_logout -rw-r--r-- 1 kchristm kchristm 3771 May 17 16:14 .bashrc drwxr-xr-x 22 kchristm kchristm 4096 Jun 2 15:53 .cache drwxr-xr-x 26 kchristm kchristm 4096 May 28 11:43 .config drwxrwxr-x 2 kchristm kchristm 4096 May 25 15:51 .dart drwxrwxr-x 4 kchristm kchristm 4096 May 25 15:51 .dartServer drwxr-xr-x 2 kchristm kchristm 4096 May 28 13:08 Desktop drwxrwxr-x 8 kchristm kchristm 4096 May 28 10:23 dev drwxr-xr-x 4 kchristm kchristm 4096 Jun 2 11:22 Documents drwxr-xr-x 4 kchristm kchristm 4096 May 26 08:37 Downloads drwxrwxr-x 10 kchristm kchristm 4096 May 26 08:58 EAGLE -rw-rw-r-- 1 kchristm kchristm 28478118 May 25 13:21 edgemont.csv drwxrwxr-x 3 kchristm kchristm 4096 May 18 12:16 env -rw-rw-r-- 1 kchristm kchristm 78 May 25 15:51 .flutter -rw-rw-r-- 1 kchristm kchristm 518 May 25 13:20 formatTime.py -rw-rw-r-- 1 kchristm kchristm 56 May 20 10:05 .gitconfig drwx------ 3 kchristm kchristm 4096 May 28 13:14 .gnupg -rw-rw-r-- 1 kchristm kchristm 35316584 May 25 13:15 hillcrest_elementary.csv -rw-rw-r-- 1 kchristm kchristm 33929904 May 25 13:15 lindon_pioneer_ln.csv drwxr-xr-x 5 kchristm kchristm 4096 May 25 11:55 .local -rw-rw-r-- 1 kchristm kchristm 85 May 25 09:57 .~lock.out.csv# drwx------ 5 kchristm kchristm 4096 May 17 16:24 .mozilla drwxrwxr-x 2 kchristm kchristm 4096 May 20 11:57 .mume drwxr-xr-x 2 kchristm kchristm 4096 May 17 16:23 Music -rw-rw-r-- 1 kchristm kchristm 29502077 May 25 13:16 oak_hills.csv drwxr-xr-x 12 kchristm kchristm 4096 May 17 18:00 .oh-my-zsh -rw-rw-r-- 1 kchristm kchristm 31997247 May 25 13:16 orem_firehouse.csv -rw-rw-r-- 1 kchristm kchristm 25575881 Mar 9 23:22 out.txt -rw-r--r-- 1 kchristm kchristm 88528 May 17 18:02 .p10k.zsh drwxrwxr-x 4 kchristm kchristm 4096 May 28 12:55 pico drwxr-xr-x 3 kchristm kchristm 4096 May 25 12:53 Pictures drwx------ 3 kchristm kchristm 4096 May 17 16:51 .pki drwxr-xr-x 6 kchristm kchristm 4096 May 17 18:01 powerlevel10k -rw-r--r-- 1 kchristm kchristm 807 May 17 16:14 .profile drwxrwxr-x 6 kchristm kchristm 4096 May 25 15:51 .pub-cache drwxr-xr-x 2 kchristm kchristm 4096 May 17 16:23 Public -rw-rw-r-- 1 kchristm kchristm 214841 May 26 09:00 seven_seg.png -rw-r--r-- 1 kchristm kchristm 10 May 17 18:00 .shell.pre-oh-my-zsh drwxr-xr-x 4 kchristm kchristm 4096 May 25 15:50 snap drwx------ 2 kchristm kchristm 4096 May 25 09:38 .ssh -rw-r--r-- 1 kchristm kchristm 0 May 17 16:56 .sudo_as_admin_successful drwxr-xr-x 2 kchristm kchristm 4096 May 17 16:23 Templates -rwxrwxr-x 1 kchristm kchristm 763 May 23 02:22 thonny-latest.sh drwxr-xr-x 2 kchristm kchristm 4096 May 17 16:23 Videos drwxrwxr-x 3 kchristm kchristm 4096 May 17 16:53 .vscode -rw-rw-r-- 1 kchristm kchristm 227 May 28 13:07 .wget-hsts drwx------ 2 kchristm kchristm 4096 May 25 15:42 .xournal -rw-r--r-- 1 kchristm kchristm 49285 May 17 18:00 .zcompdump -rw-rw-r-- 1 kchristm kchristm 50614 Jun 2 11:20 .zcompdump-EB228-EE10901-5.8 -rw------- 1 kchristm kchristm 14366 Jun 2 16:02 .zsh_history -rw-r--r-- 1 kchristm kchristm 4256 May 17 18:02 .zshrc -rw-rw-r-- 1 kchristm kchristm 94 May 17 17:59 .zshrc.pre-oh-my-zsh
As you can tell, there are many more files compared to our last command, and all the new ones are prepended with a
. to denote they are hidden. To be able to see hidden files in the GUI explorer, you would need to go into some sort of submenu to toggle the hidden file visibility whereas here we added just another letter to our command. Immediately, we can begin to see some advantages to using the shell.
Now that we can believe the shell actually represents our file system, or structure in which all of our files are organized on the computer, we should probably know how to actually move between files, or change directories
cd. In order to get into the
dev directory from my home directory, its as simple as typing in
cd and the name of the folder:
❯ cd dev
Once we hit enter, you may not notice any change in output, but just to prove that we actually moved into our folder, we can use either
pwd to verify our working directory or
ls to list the contents inside the current folder.
❯ cd dev ❯ ls christopolise.github.io pico_stuff pm_world_clock pm_world_clock_client sensor_health_analyzer ssdd
In order to get back to our previous or parent directory, just use the
.. folder to get back. What’s
..? If you noticed when we used
ls -la to see all the hidden files with our visible files, you’ll note that the first two files to show are
. refers to the current or working directory. If we were to type in
cd . nothing would happen seeing as you are moving to the place where you already exist:
❯ pwd /home/kchristm/dev ❯ cd . ❯ pwd /home/kchristm/dev
.. on the other hand, refers to the parent directory, or the one right above. So if we use
cd .., we should be able go back to our previous directory:
❯ pwd /home/kchristm/dev ❯ cd .. ❯ pwd /home/kchristm
You are well on your way to moving around in the shell!
Handling Files and Directories
Just as there are navigational commands which are analogues for actions in a normal file browser, there also exists such commands for actions such as renaming/moving, copying/pasting, and creating/removing files. Lets do a quick rapid-fire:
Although they might not seem super related, renaming files and moving files are handled by the same command. To move something, we will use the
mv command and some arguments to the command. An argument is a required field after a command, for
mv, the most basic argument configuration is
mv <target file> <target directory> where the target file is the file to be moved and the target directory is where you want to put the file.
❯ ls 7_Segment_Array_Display_Clock.ino formatTime.py Pictures apps gestures_MM.img powerlevel10k Desktop hillcrest_elementary.csv Public dev lindon_pioneer_ln.csv seven_seg.png Documents Music snap Downloads oak_hills.csv Templates EAGLE orem_firehouse.csv thonny-latest.sh edgemont.csv **out.txt** Videos env pico ❯ mv out.txt dev ❯ cd dev ❯ ls christopolise.github.io pico_stuff pm_world_clock_client ssdd **out.txt** pm_world_clock sensor_health_analyzer
In order to rename a file, we will
mv the file to a new name instead of a new directory:
❯ ls christopolise.github.io pico_stuff pm_world_clock_client ssdd **out.txt** pm_world_clock sensor_health_analyzer ❯ mv out.txt banana.txt ❯ ls **banana.txt** pico_stuff pm_world_clock_client ssdd christopolise.github.io pm_world_clock sensor_health_analyzer
Copying and pasting in the terminal is one action as opposed to its GUI counter part. To copy we will use the
cp command with the arguments of the source file and the output file.
❯ cp banana.txt banana2.txt ❯ ls **banana2.txt** pico_stuff sensor_health_analyzer **banana.txt** pm_world_clock ssdd christopolise.github.io pm_world_clock_client
To copy whole folders with contents inside, follow the
cp -r <source folder> <target directory>
To make a new directory we use the
mkdir command with the argument being the name of the new folder.
❯ mkdir test ❯ ls banana2.txt pico_stuff sensor_health_analyzer banana.txt pm_world_clock ssdd christopolise.github.io pm_world_clock_client **test**
To make a new file, we will use the
❯ touch newfile ❯ ls banana2.txt **newfile** pm_world_clock_client test banana.txt pico_stuff sensor_health_analyzer christopolise.github.io pm_world_clock ssdd
Notice how I didn’t include an extension after the file. In Linux, files are extension-agnostic, meaning I can give it whatever extension I want, but file will still behave based on its composition. This means a text file with a PNG extension will not be a picture and a picture with a TXT file will not be a text document.
To remove files or directories, we use the
rm command. A specific
rmdir command exists only to work for directories, but
rm works for both, however, an
r flag is needed if the directory is not empty:
❯ ls banana2.txt **newfile** pm_world_clock_client test banana.txt pico_stuff sensor_health_analyzer christopolise.github.io pm_world_clock ssdd ❯ rm newfile ❯ ls banana2.txt pico_stuff sensor_health_analyzer banana.txt pm_world_clock ssdd christopolise.github.io pm_world_clock_client test
Running Programs and Commands
Running programs and opening files in the shell is about as straightforward as everything you have seen up until now. You have also probably gathered that each action you could normally do outside of the shell with your mouse has its own correlating command or low level program that executes the same function. So what available commands exist inside of the operating system? Well, technically there are several directories that you could look through such as
/usr/bin or the other directories that are shown between colons when you run
❯ echo $PATH /home/kchristm/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin ❯ cd /usr/bin ❯ ls '[' debconf-escape gjs-console lastlog ntfsusermap rst2man unexpand 2to3-2.7 debconf-set-selections gkbd-keyboard-display lavadecode ntfswipe rst2odt unicode_start aa-enabled debconf-show glib-compile-schemas lcf numfmt rst2odt_prepstyles unicode_stop aa-exec debian-distro-info gnome-calculator ld nvidia-detector rst2pseudoxml uniq aconnect deb-systemd-helper gnome-calendar ld.bfd oakdecode rst2s5 unity-scope-loader acpi_listen deb-systemd-invoke gnome-characters ldd obexctl rst2xetex unlink add-apt-repository deja-dup gnome-control-center ld.gold objcopy rst2xml unlz4 addpart delpart gnome-disk-image-mounter less objdump rstart unlzma addr2line delv gnome-disks lessecho oclock rstartd unmkinitramfs alsabat desktop-file-edit gnome-extensions lessfile od rst-buildhtml unopkg alsaloop desktop-file-install gnome-extensions-app lesskey oem-getlogs rstpep2html unshare alsamixer desktop-file-validate gnome-font-viewer lesspipe on_ac_power rsync unsquashfs alsatplg devdump gnome-help lexgrog openssl rtstat unxz alsaucm df gnome-keyring libnetcfg openvt runcon unzip amidi dfu-tool gnome-keyring-3 libreoffice opldecode run-mailcap unzipsfx amixer dh_bash-completion gnome-keyring-daemon libwacom-list-local-devices orca run-parts update-alternatives amuFormat.sh dh_installxmlcatalogs gnome-language-selector link orca-dm-wrapper run-with-aspell update-desktop-database apg dh_perl_openssl gnome-logs linkicc os-prober rview update-manager apgbfm dh_python2 gnome-power-statistics linux32 p11-kit rygel update-mime-database aplay diff gnome-screenshot linux64 pacat rzsh update-notifier aplaymidi diff3 gnome-session linux-boot-prober pacmd sane-find-scanner upower apport-bug dig gnome-session-custom-session linux-check-removal pactl savelog uptime apport-cli dir gnome-session-inhibit linux-update-symlinks padsp sbattach usb-creator-gtk apport-collect dircolors gnome-session-properties linux-version pager sbkeysync usb-devices apport-unpack dirmngr gnome-session-quit listres pa-info sbsiglist usbhid-dump appres dirmngr-client gnome-session-remmina ln pamon sbsign usb_printerid appstreamcli dirname gnome-shell lnstat paperconf sbvarsign usbreset apropos dirsplit gnome-shell-extension-prefs loadkeys paplay sbverify users apt distro-info gnome-shell-extension-tool loadunimap parec scanimage utmpdump apt-add-repository dmesg gnome-shell-perf-tool localc parecord scp uuidgen apt-cache dmypy gnome-system-monitor locale partx scp-dbus-service uuidparse apt-cdrom dnsdomainname gnome-terminal locale-check passwd screendump uz apt-config domainname gnome-terminal.real localectl paste script vdir aptdcon do-release-upgrade gnome-terminal.wrapper localedef pasteurize scriptreplay vi apt-extracttemplates dpkg gnome-text-editor lodraw pasuspender sdiff view apt-ftparchive dpkg-architecture gnome-thumbnail-font loffice patch sdptool viewres apt-get dpkg-buildflags gnome-todo lofromtemplate pathchk seahorse vim.tiny apt-key dpkg-buildpackage gnome-tweaks logger pax11publish sed virtualenv apt-mark dpkg-checkbuilddeps gnome-www-browser logilab-pytest pdb2 see vmstat apt-sortpkgs dpkg-deb gold login pdb2.7 select-default-iwrap vmwarectrl apturl dpkg-distaddfile google-chrome loginctl pdb3 select-editor volname apturl-gtk dpkg-divert google-chrome-stable logname pdb3.8 sensible-browser vstp ar dpkg-genbuildinfo gpasswd loimpress pdf2dsc sensible-editor w arch dpkg-genchanges gpg lomath pdf2ps sensible-pager wall arecord dpkg-gencontrol gpg-agent look pdfattach seq watch arecordmidi dpkg-gensymbols gpgcompose lorder pdfdetach session-migration watchgnupg arm2hpdl dpkg-maintscript-helper gpgconf loweb pdffonts sessreg wc arm-none-eabi-addr2line dpkg-mergechangelogs gpg-connect-agent lowntfs-3g pdfimages setarch wdctl arm-none-eabi-ar dpkg-name gpgparsemail lowriter pdfinfo setfacl wget arm-none-eabi-as dpkg-parsechangelog gpgsm lp pdfseparate setfont whatis arm-none-eabi-c++ dpkg-query gpgsplit lpoptions pdfsig setkeycodes whereis arm-none-eabi-c++filt dpkg-scanpackages gpgtar lpq pdftocairo setleds which arm-none-eabi-cpp dpkg-scansources gpgv lpr pdftohtml setlogcons whiptail arm-none-eabi-elfedit dpkg-shlibdeps gpg-wks-server lprm pdftoppm setmetamode who arm-none-eabi-g++ dpkg-source gpg-zip lp_solve pdftops setpci whoami arm-none-eabi-gcc dpkg-split gpic lpstat pdftotext setpriv whoopsie arm-none-eabi-gcc-9.2.1 dpkg-statoverride gprof ls pdfunite setsid whoopsie-preferences arm-none-eabi-gcc-ar dpkg-trigger gpu-manager lsattr peekfd setterm word-list-compress arm-none-eabi-gcc-nm dpkg-vendor grep lsblk perl setupcon wpa_passphrase arm-none-eabi-gcc-ranlib driverless gresource lsb_release perl5.30.0 setxkbmap w.procps arm-none-eabi-gcov du groff lscpu perl5.30-x86_64-linux-gnu sftp write arm-none-eabi-gcov-dump dumpkeys grog lshw perlbug sg X arm-none-eabi-gcov-tool duplicity grops lsinitramfs perldoc sh X11 arm-none-eabi-gprof dvipdf grotty lsipc perli11ndoc sha1sum x11perf arm-none-eabi-ld dwp groups lslocks perlivp sha224sum x11perfcomp arm-none-eabi-ld.bfd echo grub-editenv lslogins perlthanks sha256sum x86_64 arm-none-eabi-nm ed grub-file lsmem pf2afm sha384sum x86_64-linux-gnu-addr2line arm-none-eabi-objcopy edit grub-fstest lsmod pfbtopfa sha512sum x86_64-linux-gnu-ar arm-none-eabi-objdump editor grub-glue-efi lsns pftp shasum x86_64-linux-gnu-as arm-none-eabi-ranlib editres grub-kbdcomp lsof pgrep shotwell x86_64-linux-gnu-c++filt arm-none-eabi-readelf efibootdump grub-menulst2cfg lspci pic showconsolefont x86_64-linux-gnu-cpp arm-none-eabi-size efibootmgr grub-mkfont lspgpot pico showkey x86_64-linux-gnu-cpp-9 arm-none-eabi-strings egrep grub-mkimage lsusb piconv showrgb x86_64-linux-gnu-dwp arm-none-eabi-strip eject grub-mklayout ltrace pidof shred x86_64-linux-gnu-elfedit as elfedit grub-mknetdir luit pinentry shuf x86_64-linux-gnu-g++ aseqdump enc2xs grub-mkpasswd-pbkdf2 lwp-download pinentry-curses simple-scan x86_64-linux-gnu-g++-9 aseqnet encguess grub-mkrelpath lwp-dump pinentry-gnome3 size x86_64-linux-gnu-gcc aspell enchant-2 grub-mkrescue lwp-mirror pinentry-x11 skill x86_64-linux-gnu-gcc-9 aspell-import enchant-lsmod-2 grub-mkstandalone lwp-request ping slabtop x86_64-linux-gnu-gcc-ar atobm env grub-mount lz ping4 slack x86_64-linux-gnu-gcc-ar-9 avahi-browse envsubst grub-ntldr-img lz4 ping6 sleep x86_64-linux-gnu-gcc-nm avahi-browse-domains eog grub-render-label lz4c pinky slogin x86_64-linux-gnu-gcc-nm-9 avahi-publish eps2eps grub-script-check lz4cat pip slxdecode x86_64-linux-gnu-gcc-ranlib avahi-publish-address epylint grub-syslinux2cfg lzcat pip3 smproxy x86_64-linux-gnu-gcc-ranlib-9 avahi-publish-service eqn gs lzcmp pkaction snap x86_64-linux-gnu-gcov avahi-resolve esc-m gsbj lzdiff pkcheck snapctl x86_64-linux-gnu-gcov-9 avahi-resolve-address eutp gsdj lzegrep pkcon snapfuse x86_64-linux-gnu-gcov-dump avahi-resolve-host-name evince gsdj500 lzfgrep pkexec snice x86_64-linux-gnu-gcov-dump-9 avahi-set-host-name evince-previewer gsettings lzgrep pkg-config soelim x86_64-linux-gnu-gcov-tool awk evince-thumbnailer gslj lzless pkill soffice x86_64-linux-gnu-gcov-tool-9 axfer ex gslp lzma pkmon software-properties-gtk x86_64-linux-gnu-gold b2sum expand gsnd lzmainfo pkttyagent sort x86_64-linux-gnu-gprof baobab expiry gst-device-monitor-1.0 lzmore pl2pm sotruss x86_64-linux-gnu-ld base32 expr gst-discoverer-1.0 m2300w pldd spd-conf x86_64-linux-gnu-ld.bfd base64 factor gst-inspect-1.0 m2300w-wrapper plog spd-say x86_64-linux-gnu-ld.gold basename faillog gst-launch-1.0 m2400w plymouth speaker-test x86_64-linux-gnu-nm bash faked-sysv gst-play-1.0 make pmap speech-dispatcher x86_64-linux-gnu-objcopy bashbug faked-tcp gstreamer-codec-install make-first-existing-target pnm2ppa spice-vdagent x86_64-linux-gnu-objdump bc fakeroot gst-typefind-1.0 mako-render pod2html splain x86_64-linux-gnu-pkg-config bccmd fakeroot-sysv gtbl man pod2man split x86_64-linux-gnu-python2.7-config bdftopcf fakeroot-tcp gtf mandb pod2text splitfont x86_64-linux-gnu-python2-config bdftruncate fallocate gtk-builder-tool manpath pod2usage spotify x86_64-linux-gnu-python3.8-config bitmap false gtk-encode-symbolic-svg man-recode podchecker sprof x86_64-linux-gnu-python3-config bluemoon fc-cache gtk-launch mapscrn podselect ss x86_64-linux-gnu-ranlib bluetoothctl fc-cat gtk-query-settings mattrib poff ssh x86_64-linux-gnu-readelf bluetooth-sendto fc-conflist gtk-update-icon-cache mawk pon ssh-add x86_64-linux-gnu-size bmtoa fc-list gunzip mbadblocks POST ssh-agent x86_64-linux-gnu-strings boltctl fc-match gvfs-cat mcat ppdc ssh-argv0 x86_64-linux-gnu-strip bootctl fc-pattern gvfs-copy mcd ppdhtml ssh-copy-id x86_64-pc-linux-gnu-pkg-config brltty fc-query gvfs-info mcheck ppdi ssh-import-id xargs brltty-ctb fc-scan gvfs-less mclasserase ppdmerge ssh-import-id-gh xauth brltty-trtxt fc-validate gvfs-ls mcomp ppdpo ssh-import-id-lp xbiff brltty-ttb fgconsole gvfs-mime mcookie pphs ssh-keygen xbrlapi broadwayd fgrep gvfs-mkdir mcopy pr ssh-keyscan xcalc browse file gvfs-monitor-dir md5sum precat start-pulseaudio-x11 xclipboard bsd-from file2brl gvfs-monitor-file md5sum.textutils preconv startx xclock bsd-write file-roller gvfs-mount mdel preunzip stat xcmsdb btattach fincore gvfs-move mdeltree prezip static-sh xconsole btmgmt find gvfs-open mdig prezip-bin stdbuf xcursorgen btmon findmnt gvfs-rename mdir print strace xcutsel bunzip2 firefox gvfs-rm mdu printafm strace-log-merge xdg-dbus-proxy busctl fish gvfs-save mesa-overlay-control.py printenv strings xdg-desktop-icon busybox fish_indent gvfs-set-attribute mesg printerbanner strip xdg-desktop-menu bwrap fish_key_reader gvfs-trash mformat printer-profile stty xdg-email bzcat flock gvfs-tree migrate-pubring-from-classic-gpg printf stubgen xdg-icon-resource bzcmp fmt gzexe mimeopen prlimit su xdg-mime bzdiff fold gzip mimetype prove sudo xdg-open bzegrep fonttosfnt h2ph min12xxw prtstat sudoedit xdg-screensaver bzexe foo2ddst h2xs minfo ps sudoreplay xdg-settings bzfgrep foo2ddst-wrapper hbpldecode miniterm ps2ascii sum xdg-user-dir bzgrep foo2hbpl2 hciattach mkdir ps2epsi symcryptrun xdg-user-dirs-gtk-update bzip2 foo2hbpl2-wrapper hciconfig mkfifo ps2pdf symilar xdg-user-dirs-update bzip2recover foo2hiperc hcitool mkfontdir ps2pdf12 sync xditview bzless foo2hiperc-wrapper hd mkfontscale ps2pdf13 syslinux xdpyinfo bzmore foo2hp head mkisofs ps2pdf14 syslinux-legacy xdriinfo c++ foo2hp2600-wrapper HEAD mkmanifest ps2pdfwr system-config-printer xedit c89 foo2lava helpztags mk_modmap ps2ps system-config-printer-applet Xephyr c89-gcc foo2lava-wrapper hex2hcd mknod ps2ps2 systemctl xev c99 foo2oak hexdump mksquashfs ps2txt systemd xeyes c99-gcc foo2oak-wrapper hipercdecode mktemp psfaddtable systemd-analyze xfd cal foo2qpdl host mkzftree psfgettable systemd-ask-password xfontsel calendar foo2qpdl-wrapper hostid mlabel psfstriptable systemd-cat xgamma calibrate_ppa foo2slx hostname mmcli psfxtable systemd-cgls xgc canberra-gtk-play foo2slx-wrapper hostnamectl mmd psicc systemd-cgtop xhost cancel foo2xqx hp-align mmount pslog systemd-delta xinit captoinfo foo2xqx-wrapper hp-check mmove pstree systemd-detect-virt xinput cat foo2zjs hp-clean mokutil pstree.x11 systemd-escape xkbbell catchsegv foo2zjs-icc2ps hp-colorcal monitor-sensor ptar systemd-hwdb xkbcomp catman foo2zjs-pstops hp-config_usb_printer more ptardiff systemd-id128 xkbevd cautious-launcher foo2zjs-wrapper hp-doctor mount ptargrep systemd-inhibit xkbprint cc foomatic-rip hp-firmware mountpoint ptx systemd-machine-id-setup xkbvleds cd-create-profile fprintd-delete hp-info mousetweaks pulseaudio systemd-mount xkbwatch cd-fix-profile fprintd-enroll hp-levels mpartition pwd systemd-notify xkeystone cd-iccdump fprintd-list hp-logcapture mrd pwdx systemd-path xkill cd-it8 fprintd-verify hp-makeuri mren py3clean systemd-resolve xload c++filt free hp-pkservice mscompress py3compile systemd-run xlogo chacl from hp-plugin msexpand py3versions systemd-socket-activate xlsatoms chage ftp hp-plugin-ubuntu mshortname pyclean systemd-stdio-bridge xlsclients chardet3 funzip hp-probe mshowfat pycompile systemd-sysusers xlsfonts chardetect3 fuser hp-query mt pydoc systemd-tmpfiles xmag chattr fusermount hp-scan mt-gnu pydoc2 systemd-tty-ask-password-agent xman chcon futurize hp-setup mtools pydoc2.7 systemd-umount xmessage check-language-support fwupdagent hp-testpage mtoolstest pydoc3 tabs xmodmap cheese fwupdate hp-timedate mtr pydoc3.8 tac xmore chfn fwupdmgr htop mtrace pygettext2 tail Xorg chgrp fwupdtool hwe-support-status mtr-packet pygettext2.7 tar xournal chmod fwupdtpmevlog i386 mtype pygettext3 taskset xprop choom g++ i686-linux-gnu-pkg-config mutter pygettext3.8 tbl xqxdecode chown g++-9 ibus mv pygmentize tee xrandr chrome-gnome-shell gamemoded ibus-daemon mxtar pyjwt3 telnet xrdb chrt gamemoderun ibus-setup mypy pylint telnet.netkit xrefresh chsh gamma4scanimage ibus-table-createdb mzip pyreverse tempfile xsel chvt gapplication iceauth namei python test x-session-manager ciptool gatttool ico nano python2 tgz xset ckbcomp gcalccmd iconv nautilus python2.7 thunderbird xsetmode cksum gcc id nautilus-autorun-software python2.7-config tic xsetpointer clear gcc-9 iecset nautilus-sendto python2-config tificc xsetroot clear_console gcc-ar ijs_pxljr nawk python3 time xsetwacom cmake gcc-ar-9 im-config nc python3.8 timedatectl xsm cmp gcc-nm im-launch ncal python3.8-config timeout xstdcmap code gcc-nm-9 info nc.openbsd python3-config tload xsubpp codepage gcc-ranlib infobrowser ncurses5-config python3-futurize toe x-terminal-emulator col gcc-ranlib-9 infocmp ncurses6-config python3-pasteurize top xvidtune colcrt gcore infotocap ncursesw5-config python-config totem xvinfo colormgr gcov inputattach ncursesw6-config pyvenv totem-video-thumbnailer Xwayland colrm gcov-9 install neqn pyversions touch xwd column gcov-dump install-info netcat qpdldecode tput x-window-manager comm gcov-dump-9 install-printerdriver netkit-ftp quirks-handler tr xwininfo compose gcov-tool instmodsh networkctl ranlib tracepath xwud corelist gcov-tool-9 intel-virtual-output networkd-dispatcher rbash traceroute6 x-www-browser cp gcr-viewer ionice newgrp rcp traceroute6.iputils xxd cpack gdb ip ngettext rctest tracker xz cpan gdb-add-index ipcmk nice rdiffdir transicc xzcat cpan5.30-x86_64-linux-gnu gdbserver ipcrm nisdomainname rdma transmission-gtk xzcmp cpio gdbtui ipcs nl readelf transset xzdiff cpp gdbus ipod-read-sysinfo-extended nm readlink troff xzegrep cpp-9 gdialog ipod-time-sync nm-applet realpath true xzfgrep c_rehash gdk-pixbuf-csource ippfind nmcli red truncate xzgrep crontab gdk-pixbuf-pixdata ipptool nm-connection-editor remmina trust xzless csplit gdk-pixbuf-thumbnailer iptables-xml nm-online remmina-file-wrapper tset xzmore ctest gdmflexiserver ischroot nmtui remmina-gnome tsort yelp ctstat gdm-screenshot isdv4-serial-debugger nmtui-connect rename.ul ttfread yes cupstestppd gedit isdv4-serial-inputattach nmtui-edit rendercheck tty ypdomainname curl gencat isodump nmtui-hostname renice tzselect zcat cut genisoimage isoinfo nohup reset ua zcmp cvt geqn isovfy notify-send resizecons ubuntu-advantage zdiff cvtsudoers GET ispell-wrapper nproc resizepart ubuntu-bug zdump dash getconf join nroff resolvectl ubuntu-core-launcher zegrep date geteltorito journalctl nsenter rev ubuntu-distro-info zenity dbus-cleanup-sockets getent jpgicc nslookup rfcomm ubuntu-drivers zfgrep dbus-daemon getfacl json_pp nstat rgrep ubuntu-report zforce dbus-launch getkeycodes kbdinfo nsupdate rhythmbox ubuntu-security-status zgrep dbus-monitor getopt kbd_mode ntfs-3g rhythmbox-client ucf zip dbus-run-session gettext kbxutil ntfs-3g.probe rlogin ucfq zipcloak dbus-send gettext.sh kernel-install ntfscat rm ucfr zipdetails dbus-update-activation-environment ghostscript kerneloops-submit ntfscluster rmdir ucs2any zipgrep dbus-uuidgen ginstall-info keyring ntfscmp rnano udevadm zipinfo dc gio kill ntfsdecrypt routef udisksctl zipnote dconf gio-querymodules killall ntfsfallocate routel ul zipsplit dd gipddecode kmod ntfsfix rpcgen ulockmgr_server zjsdecode ddstdecode git kmodsign ntfsinfo rrsync umax_pp zless deallocvt git-receive-pack l2ping ntfsls rsh umount zmore debconf git-shell l2test ntfsmove rst2html uname znew debconf-apt-progress git-upload-archive laptop-detect ntfsrecover rst2html4 unattended-upgrade zsh debconf-communicate git-upload-pack last ntfssecaudit rst2html5 unattended-upgrades zsh5 debconf-copydb gjs lastb ntfstruncate rst2latex uncompress
Sorry about that, I know the output is ridiculously long, but that is the point I am trying to make. There are so many commands, so trying to remember them all at this point is quite useless. Your best bet is to do a quick Google search and see which command is best for your use case. Sometimes you don’t even have the command available and will have to install it through your package manager, but that is a different topic for another article.
There are so many flags for each command, how am I supposed to know what they do? Do I have to do a Google search each time? Maybe. But I would recommend trying to read the manual, before doing that. You can read the manual for the command by typing
man <name of command> and getting a nice overview of what it can do. For example, when trying to find all the different ways we can list the contents of our directory, just try
❯ man ls LS(1) User Commands LS(1) NAME ls - list directory contents SYNOPSIS ls [OPTION]... [FILE]... DESCRIPTION List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified. Mandatory arguments to long options are mandatory for short options too. -a, --all do not ignore entries starting with . ... (This goes on for a bit, to exit it, just hit q on your keyboard)
As mentioned before, Linux is extension-agnostic, but normally people are nice enough to leave them in anyways. To open text files, there are many different commands that you can use:
cat is a simple command that will spit out the contents of your file onto the terminal screen:
❯ cat test.txt Hello, World!
However this can prove to be a little cumbersome when your files contain thousands of lines like
❯ cat banana.txt #datatype measurement,dateTime:RFC3339,double,double,double,double,double loc,timestamp,PM1_0,PM2_5,PM10_0,temperature,humidity orem_firehouse,2020-02-01T00:00:50Z,3.41,6,6.76,51,27 orem_firehouse,2020-02-01T00:02:50Z,3.07,5.65,6.16,51,26 orem_firehouse,2020-02-01T00:04:50Z,3.21,6.14,6.49,51,26 orem_firehouse,2020-02-01T00:06:50Z,3.99,6.14,7.48,50,26 orem_firehouse,2020-02-01T00:08:50Z,3.35,5.44,6.13,50,26 orem_firehouse,2020-02-01T00:10:50Z,3.39,6.02,6.59,50,27 orem_firehouse,2020-02-01T00:12:50Z,3.85,6.81,7.9,50,27 orem_firehouse,2020-02-01T00:14:50Z,4.3,6.72,7.61,51,27 orem_firehouse,2020-02-01T00:16:50Z,3.82,6.89,7.38,51,27 orem_firehouse,2020-02-01T00:18:50Z,3.64,6.17,6.67,51,27 ... (literally continues for 50,000+ lines)
To fix this problem, we can use the
less command which will show the text in a scrollable screen where you can exit by pressing the
There are other alternatives to these commands and some will work better than others in certain situations, but this will be your job to figure it out when the time comes.
So lets say I have a program that is supposed to be executable from the folder because it is a shell script or a compiled program but is not in one of the directories shown in
echo $PATH, how am I supposed execute it? Well I am very glad you asked such a specific question 😉. The behavior of these programs will largely depend on the environment in which they run and the types of programs they are. If it is a program that is meant to be run through the terminal, executing it in the shell will cause the programs output to be placed on the terminal screen until the program’s execution is finished. However, if you are trying to run a graphical program, you should take the following into account:
- Am I running a headless instance? (When I turn the computer on, am I greeted by the shell and not a GUI)
- Am I connected to a remote shell? (Did I use
sshto connect to a remote computer?)
- Am I using a terminal emulator inside of a desktop environment? (Did I click on a program that is called Terminal?)
If you are using one of the first two options, running a graphical program WILL NOT WORK (there is an
x flag that you can use for
ssh, but that is a different discussion for a different article.)
If you are using the last option, executing a graphical program will have some interesting advantages. You most likely will be able to see debug statements scroll across the terminal screen as the program runs in a separate window.
Regardless of which situation you find yourself in, executing a program is still the same across the board.
./ is prepended to the name of the executable you are trying to run. Alternatively, you can use
sh followed by the program in the folder or its path as the argument.
❯ ./test.sh Hello World! ❯ sh test.sh Hello World!
Inevitably, when you try to run a program, you will encounter the dreaded error:
❯ ./test.sh zsh: permission denied: ./test.sh
There are several routes you can take when you encounter this issue.
sudo is the command you run when you want to execute a program as administrator, or to make the superuser do it. BE EXTREMELY CAREFUL WHEN DOING THIS!!! When you do something as superuser in a Linux system, there is no undoing this unless you have implemented your own fail-safe. You can RUIN your entire system if you are not careful.
The next option requires a little knowledge on how file permissions work. As this is an extensive topic that probably deserves an article of its own, I will suggest a quick fix and write another article if one is desired.
chmod is a tool which allows you to edit the file permissions of any program which can be seen by executing
ls -l . You can refer to some of the links below to decipher what they mean, but what we need to do is add the argument
+x in order to add execution privileges.
❯ ./test.sh zsh: permission denied: ./test.sh ❯ chmod +x test.sh ❯ ./test.sh Hello World!
With this brief introduction, you are well on your way to breaking in that new distro of yours. Learning the shell may have a steep learning curve at first, but its effects are long lasting. The benefits come from the common struggle between perception and experience. A good user interface makes a system usable based on the user’s perception. Things such as double-clicking, windows, and countless specialized tools allow a person to intuit there way through a project, bringing a minimal amount of discomfort. Conversely, when the user chooses to embrace discomfort and use a less intuitive interface such as the shell, they will gain experience with a tool that will allow them to become the master of their system and gain much tangential understanding along the way.
(More to come as suggested, just leave a comment below!)