Introduction to BASH Basics - Part 2: Useful BASH commands for Single Board Computers

Last time, we learned about the ‘ls’ and ‘tree’ commands. While looking at things is nice, it's more fun to actually do something with our data. This article contains a list of the common commands for manipulating data. The command and its explanation are kept very brief to avoid writing a Linux encyclopedia and boring you all to death. They should just bring the existence of a BASH command to your attention.

As a reminder, whenever we want to learn more about something, typing ‘man ’ into a Terminal window will give the usage syntax as well as all the options available for this program. Be careful, though, because the man pages often have content accumulated over decades and can be hard to digest, especially for beginners. If you want to hit the ground running, open www.explainshell.com in your browser to get commands explained, like the examples mentioned here. For useful starters to build your own commands, use the TLDR pages at tldr.ostera.io. Compare the manual for the tar command with the TLDR version and you will see what I mean.

Basic BASH commands

The most used and most basic commands are:

  • cd - change directory. ‘cd /’ changes to the root directory, ‘cd ~’ back to the user’s home directory.
  • mkdir - make a directory. Try ‘mkdir ~/test’ to make a subdirectory in your home folder named test.
  • cp - copy files. ‘cp /path/to/file /home/odroid/test/’ generates a copy at the freshly made directory from before. With the -R option, you can recursively copy files and directories.
  • mv - move files. The syntax is the same as cp, but the file gets removed after the copy was successfully made.
  • rm - remove files

$ rm exampleFile.txt

  • cat - concatenate files. cat reads from standard input and writes to standard output if no other options are given. If you use cat file, it writes the contents of file to the console, the standard output. Try ‘cat /etc/fstab’ for an example.
  • less - If you want to read longer files on the console. ‘less filename’ shows the content of file and pauses after each page. You can advance with space and go back with b and q to quit.

$ less exampleFile.txt

  • head and tail - By default, head file shows the first 10 lines of file, while tail of a file shows the last 10 lines of file.

$ tail exampleFile.txt
$ head exampleFile.txt

  • tar and zip - For archiving files. tar cf archive.tar /home/odroid/test/ archives the test directory and all of its contents. If you add the switch z (tar czf), the archive gets zipped afterwards.
  • sudo and su - For everything requiring elevated rights, you prepend a sudo to run the command as root, the super user. cat /etc/sudoers will fail. If you use sudo cat /etc/sudoers, you can read the file. su is 'switch user' If you have assigned a password to the root user or have other users on the system, you can switch to them with this command. With sudo -i, you can also switch to an elevated command prompt and work as root until you exit with.

$ sudo -i

  • exit - to exit the elevated prompt or the shell. Useful also for remote connections.

$ exit

  • ssh - You can login to a remote console of your ODROID with this. This is where the BASH console really shines. Sit at your PC, log into the ODROID where ever it is and work as if you are sitting in front of it. It is very inconvenient to use a GUI in this case, this is why the console and BASH on your SBC are more important. On a desktop PC, you may be able to avoid the command line most of the time. To connect with ssh you need the computer’s or ODROID’s IP address and the username you want to login as. For example the user is ‘odroid’ and the IP is ‘192.168.0.1’.

$ ssh odroid@192.168.0.1

  • grep - Shows files which contain a certain text pattern. You want to know which files in the /etc/ directory contain the word 'Ubuntu'? grep -rnw '/etc/' -e 'Ubuntu' gives you the answer.

$ grep -rnw ‘/etc/’ -e Ubuntu

  • find - You can use find to find files with almost all imaginable criteria, and act on them. Simplest example: find /home/ -name '*test*' finds all files and directories which contain 'test'. find /home/odroid/ -type f -size +1M -mtime -30 is a more elaborate example. It finds all files (not directories) in /home/odroid bigger than 1 MB modified in the last 30 days. You can also use Explainshell.com to see what it does.

Figure 01 - explainshell.com explaining our find command

  • sort - sorts files.
  • df and du - disk free and disk usage show how much space you have left with df or how much your individual files and folders use with du -ch.
  • ps and kill, killall - ps lists running processes, if you want to see everything running, use ps aux. The process number used with kill, so kill , will kill the process by sending a signal to terminate the process. killall kills all processes with this name.

$ ps aux
$ kill

  • mount and umount - Mount external devices and drives with mount /dev/ /path, unmount them with umount /dev/.
  • dd - With dd, you can write from everywhere to everywhere. It's also called the disk destroyer for a reason, so be careful! dd if=/dev/mmcblk0 of=/home/odroid/mbrbackup bs=512 count=1 makes a copy of the master boot record. Very nice when you want to flash a new SD card.

$ dd  if=/input/path of=/output/path

  • shutdown and reboot - they shutdown and reboot your SBC. Several options available.

BASH expansion and wildcards

  • * and ? - ls *.txt lists all files ending with .txt. With ls Image??.jpg, you can list files with names like Image00.jpg or ImageAB.jpg.
  • [abc] - ls /dev/sd[abcd]1 lists the partitions /dev/sda1, /dev/sdb1, /dev/sdc1 and /dev/sdd1.
  • | as selector - With mount | grep 'mmc\|sd', you can list only mounted eMMC, SD cards or external drives or sticks. It expands to 'everything with mmc OR sd in the name'.

Advanced BASH commands - redirection, data flow and loops

  • stdin, stdout and stderr - These three files (remember everything in UNIX is a file) always exist. stdin is the keyboard, stdout is the screen and stderr are the error messages output to the screen.
  • | - You can pipe output from one program to the next. The find example output from above is much easier to read if you use find /home/odroid -type f -size +1M -mtime -30 -exec du -h {} \; 2>/dev/null | sort -n. The output from find gets used by du to show the sizes, and all errors from stderr go to /dev/null, the sink for unnecessary data. Once again, if paste that command in explainshell.com you will see a broken down view of what each part does.

$ find /home/odroid -type f -size +1M -mtime -30 -exec du -h {} \; 2>/dev/null | sort -n

    • /dev/zero and /dev/null are the source for null bytes and the sink for everything you don't need.
    • > and <, >> and << - These redirect output or input to files. ls *.txt > texts.list generates a list of text files in the current directory. ls Documents/*.txt >> texts.list would append the list of .txt files in the Documents directory to it. 2> is the stderr output. The 2>/dev/null part in the example above redirects all error messages away from the console into the Big Bit Bucket.

for, do, done - BASH loops can be constructed with these commands.

if, then, else - Advanced loop construct, mainly for scripts.

Practical application example

Let's do an example to see the power of the shell and of loops. Your Pictures folder contains several subdirectories, each of which you want to compress into an individual archive to mail to someone else. This is easily done with the GUI if you have just your folders from your travels labeled 'USA', 'South Korea' and 'Spain': right-click, select compress, and you’re done.

Now think about the same problem, but with folders generated by a program from a camera attached to the ODROID. If you have 100 folders or more, this task becomes mind-numbingly repetitive. Here is where BASH comes to the rescue!

If we use the ‘ls -F’ command to list a directory, symbols are added to the names according to their type. Directories have a slash appended, which is also how BASH sees them. Aid to memory: The slash could be part of the path name to a file in this directory, so they get a trailing slash:

$ for i in */; do zip -r "${i%/}.zip" "$i"; done
This command gets all directories in the directory we are in: the for i in */; part. For each of them, we do the following: zip -r "${i%/}.zip", where $i is the i variable we introduced before, i%/ is the name without the slash, and "${i%/}.zip" is the directory name with .zip attached; directory 2018 05 20 would give the archive 2018 05 20.zip. The quotes avoid that names with spaces are treated as two different names instead, which could have disastrous consequences. After this command has run for all i, we are done.

A short one-liner saves a lot of tedious work. This is what makes BASH so attractive. In the next article, we will look at startup and login and customizing the BASH prompt.

Be the first to comment

Leave a Reply