Table of contents
- How to get command-specific help: '--help'
- Check a particular command's progress!
- Run a command as root: sudo
- Working with Files / Folders
- Listing files: ls
- The universal Linux directories: . & ..
- Changing directories: cd
- Creating & Removing files and folders: touch, rm, mkdir, rmdir
- Copying files: cp
- Moving files: mv
- Renaming files: mv (or cp)
- Compressing & Extracting files: zip, unzip
- Using a package manager (apt)
Let's face it. We spend most of our screen time in front of the fancy graphical user interface of our computers, and some of us even believe that it is the only way to do things! Well, this may be true in some cases, but not always. In fact, for a lot of use cases, the command line is going to be a faster and more consistent option than its GUI alternatives.
The Linux Command Line (CLI), also called the terminal, is just a simple shell where you can input commands to get tasks done. By default, the command line only supports standard text input from the keyboard.
You type in a command, and you get the output. It's as simple as that.
Now, as you may know, there are a variety of Linux distributions and a lot of shells (bash, zsh, ksh etc.) available. But, while they may look different or use different colours to display text, the commands you'll use to interact with them will still be the same.
Now that we've got the theory out of the way, let's jump right into running some basic Linux commands!
How to get command-specific help: '--help'
Before we start exploring the various commands we can use, let's take a brief moment to learn how to get more information/help related to a particular command, right from the terminal itself! Let's take the 'ls' command as an example.
[1 | log] $ ls --help
Usage: ls [OPTION]... [FILE]...
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 .
-A, --almost-all do not list implied . and ..
--author with -l, print the author of each file
...
As you can see, the '--help' flag provides you with all the information you need to know how the command works, and what flags you can use with it.
This flag works with almost all commands. Remember to use it whenever you feel lost or just want to learn more about what the command can do! ๐
Check a particular command's progress!
Progress, as the name specifies, displays the progress of a particular command in Linux. As you may have noticed, commands like cp or mv do not display any progress indicator by default. If you're transferring large files, it may look like the terminal session is 'stuck', when in reality, everything's fine. It's just not showing you that the task is being performed. This is why this command is so useful.
To get started, install progress. It's can be easily installed from the official repositories of almost all Linux distributions.
$ apt install progress # Debian/Ubuntu
$ dnf install progress # Fedora
$ pacman -S progress # Arch Linux
Once progress is installed, use this syntax to check the progress of any command.
Let's see all the commands supported by default, by running command #1. Note that this list is not exhaustive. In reality, it supports a lot more commands.
Command #2 shows the syntax of using the command. We added the -m flag to enable continuous monitoring.
[2 | downloads] $ progress --help #1
progress - Coreutils Viewer
---------------------
Shows progress on file manipulations (cp, mv, dd, ...)
Monitored commands (default, you can add virtually anything):
cp mv dd tar bsdtar cat rsync scp grep fgrep egrep cut sort md5sum sha1sum sha224sum sha256sum sha384sum sha512sum adb gzip gunzip bzip2 bunzip2 xz unxz lzma unlzma 7z 7za zip unzip zcat bzcat lzcat coreutils split gpg
...
[3 | linux] $ zip ../linux.zip * | progress -m #2
# The 'progress' session
[1583670] zip /hd/sayan/backup/linux/Anaconda3-2023.03-Linux-x86_64.sh
4.0% (34.7 MiB / 860.1 MiB) 15.7 MiB/s remaining 0:00:52
Run a command as root: sudo
By default, any user (except root) is a standard user in Linux. This means that the user cannot unintentionally modify core Linux system components, by default. However, sometimes we do need to run a particular command as root, or superuser. In that case, we need to temporarily provide that command with superuser permissions.
In this example, we're trying to use pacman (a package manager) to update the repositories. It needs superuser access since it has to update the local repository database.
Command #1 shows the standard behaviour for any command that needs superuser access, and you try to run it as a standard user. It'll either throw an error or just fail to execute.
Command #2 shows how to run a command with 'sudo' i.e. with superuser access. Linux will temporarily grant the command superuser access till it finishes executing.
[4 | testdir] $ pacman -Sy #1
error: you cannot perform this operation unless you are root.
[5 | testdir] $ sudo pacman -Sy #2
:: Synchronizing package databases...
core is up to date
extra 1766.3 KiB 1436 KiB/s 00:01 [#################################] 100%
...
Working with Files / Folders
Navigating between various files & folders (or directories) is an integral part of the Linux command line experience. Here are some commands you can use here.
Listing files: ls
The aptly named 'ls' command allows us to list all files and directories in the directory we're currently in.
ls -> This displays everything in our current directory, excluding the hidden stuff (i.e. the files/directories that begin with a dot (.) - #1
ls -a -> This displays everything, including all the hidden stuff. - #2
ls -l -> This displays everything in a more human-readable format, along with the file/directory properties. - #3
ls -h -> This displays all the file sizes in a more human-readable format, i.e. 4.0K (4KB) instead of 4096 (4096 bytes).
ls -al / ls -la -> This is an interesting behaviour in Linux. You can merge multiple flags and use them together! This is the same as running 'ls -a -l', and it essentially displays all the files in a more human-readable format, while also including the hidden ones. - #4
[6 | hd] $ ls #1
sayan software SteamLibrary
[7 | hd] $ ls -a #2
. .. sayan software SteamLibrary .Trash-1000
[8 | hd] $ ls -l #3
total 12
drwxr-xr-x 5 sayan sayan 4096 Feb 2 07:14 sayan
drwxr-xr-x 11 sayan sayan 4096 Apr 7 10:21 software
drwxr-xr-x 3 sayan sayan 4096 Jan 30 12:28 SteamLibrary
[9 | hd] $ ls -lh #4
total 12K
drwxr-xr-x 5 sayan sayan 4.0K Feb 2 07:14 sayan
drwxr-xr-x 11 sayan sayan 4.0K Apr 7 10:21 software
drwxr-xr-x 3 sayan sayan 4.0K Jan 30 12:28 SteamLibrary
[10 | hd] $ ls -alh #4
total 24K
drwxr-xr-x 6 sayan root 4.0K Feb 25 19:19 .
drwx------ 40 sayan sayan 4.0K Apr 7 20:32 ..
drwxr-xr-x 5 sayan sayan 4.0K Feb 2 07:14 sayan
drwxr-xr-x 11 sayan sayan 4.0K Apr 7 10:21 software
drwxr-xr-x 3 sayan sayan 4.0K Jan 30 12:28 SteamLibrary
drwx------ 4 sayan sayan 4.0K Mar 26 20:57 .Trash-1000
The universal Linux directories: . & ..
I'd like to take a brief moment to talk about the significance of these two directories.
. -> This means the current directory (or the present working directory) - #1
.. -> This is the directory 1 step back, that is the parent directory (of the current directory). - #2
Confused? Let's take some examples. Here, we will simply use 'ls' to list the contents of our current & parent directories.
[11 | hd] $ ls . #1
sayan software SteamLibrary
[12 | hd] $ ls .. #2
code Documents testdir Pictures
Desktop Downloads Music
As you can see here, 'ls .'(which is the same as 'ls') prints the contents of our current directory.
Meanwhile, 'ls ..' prints the contents of the parent directory!
I mentioned that these two directories are 'universal' because they work everywhere, no matter what your current working directory is.
Changing directories: cd
This command allows you to change your current directory to a different one. In this example,
we're initially in the '/tmp' directory.
First, we create a new directory testdir. - #1
Now, we change our current directory to testdir. - #2
The command pwd shows the present working directory, which is our current directory. - #3
[13 | tmp] $ mkdir testdir #1
[14 | tmp] $ cd testdir #2
[15 | testdir] $ pwd #3
/tmp/testdir
Creating & Removing files and folders: touch, rm, mkdir, rmdir
The 'rm' command stands for 'remove'. If we want to delete a file using this command, we can just use it directly, as in 'rm test1.txt'. However, if we want to delete directories, we need to use the '-r' flag, which stands for recursive i.e. it recursively deletes a directory, as well as all files within that directory.
Let's learn by doing, shall we? Right now the directory we just created, testdir, is empty. Let's use these commands now.
First, create 2 directories, dir1 & dir2. - #1
Create 2 text files, test1.txt & test2.txt. - #2
Remove both the directories, using rmdir & rm -r. - #3, #4
Remove both the files. - #5
[16 | testdir] $ mkdir dir1 dir2 #1
[17 | testdir] $ touch test1.txt test2.txt #2
[18 | testdir] $ ls
dir1 dir2 test1.txt test2.txt
[19 | testdir] $ rmdir dir1 #3
[20 | testdir] $ rm -r dir2 #4
[21 | testdir] $ ls
test1.txt test2.txt
[22 | testdir] $ rm test1.txt test2.txt #5
[23 | testdir] $ ls
[24 | testdir] $
Copying files: cp
For demonstrating this, I'll first create 2 directories, dir1 & dir2. Then, I'll copy the file 'test.txt' to dir1, and finally move the same file to dir2.
[25 | testdir] $ mkdir dir1 dir2
[26 | testdir] $ ls
dir1 dir2 test.txt
[27 | testdir] $ cp test.txt ./dir1/ #1
[28 | testdir] $ cp test.txt ./dir1/test2.txt #2
[29 | testdir] $ ls dir1
test2.txt test.txt
[30 | testdir] $ ls
dir1 dir2 test.txt
In #1, we just copied the file test.txt to dir1.
In #2, we not only copied the file but also renamed it to test2.txt! This is another interesting behaviour in Linux.
Moving files: mv
In Linux, the mv command is used both for moving & renaming files. Let's see how this works.
[31 | testdir] $ touch test1.txt test2.txt #1
[32 | testdir] $ mv test1.txt ./dir2/ #2
[33 | testdir] $ ls dir2
test1.txt
[34 | testdir] $ ls
dir1 dir2 test2.txt test.txt
[35 | testdir] $ mv test2.txt testnew.txt #3
[36 | testdir] $ ls
dir1 dir2 testnew.txt test.txt
[37 | testdir] $ mv testnew.txt test.txt #4
[38 | testdir] $ ls
dir1 dir2 test.txt
We create 2 files, test1.txt & test2.txt - #1
We move test1.txt to dir2. - #2
The current contents of our working directory are as shown by command #4.
Next, we rename test2.txt to testnew.txt. - #5
Now, let's attempt to rename testnew.txt to test.txt.
But wait, we already have a file named test.txt (as shown in command #6) in our directory! What do you think will happen if we run command #7 anyways? Well, mv will replace our existing file, test.txt with the file we want to rename, testnew.txt.
Be careful when transferring/renaming files using traditional Linux commands like cp & mv. If there's an existing file in the destination directory with the same name as the file you're trying to transfer, the existing file will be replaced without warning. You have been warned!
Renaming files: mv (or cp)
The way you rename files in Linux is pretty simple if you can understand the logic behind it. You simply 'move the file to the same directory under a different name' to rename it. Both cp & mv can be used to rename files, depending on the context.
Now, let's rename test.txt to test1.txt. - #1
[39 | testdir] $ ls
dir1 dir2 test.txt
[40 | testdir] $ mv test.txt test1.txt #1
[41 | testdir] $ ls
dir1 dir2 test1.txt
Compressing & Extracting files: zip, unzip
Many-a-times, we need to compress files & send it to someone else. The traditional way is to use a file archiving utility, like WinRAR or PeaZip on Windows. However, zip, unzip as well as tar are not only pre-installed in most Linux distributions, and are also super easy to use!
First, let's see how to use zip & unzip. Command #1 returns the current content of the directory, testdir. Let's create 2 zip archives, archive1.zip & archive2.zip.
archive1.zip will contain dir1 & test1.txt. To add directories, we need to specify the -r flag after the command. To add files only, omit the -r flag.
archive2.zip will contain all the content in the current directory.
[42 | testdir] $ ls
dir1 dir2 test1.txt
[43 | testdir] $ zip -r archive1.zip dir1 test1.txt #1
adding: dir1/ (stored 0%)
adding: test1.txt (stored 0%)
[44 | testdir] $ zip -r archive2.zip * #2
adding: archive1.zip (stored 0%)
adding: dir1/ (stored 0%)
adding: dir2/ (stored 0%)
adding: test1.txt (stored 0%)
Now, let's see what's in the archives using the unzip command. We will use the -l flag for this purpose, which stands for listing the archive contents.Bash Scripting
[45 | testdir] $ unzip -l archive1.zip #1
Archive: archive1.zip
Length Date Time Name
--------- ---------- ----- ----
0 2023-05-12 15:31 dir1/
0 2023-05-12 15:31 test1.txt
--------- -------
0 2 files
[46 | testdir] $ unzip -l archive2.zip #2
Archive: archive2.zip
Length Date Time Name
--------- ---------- ----- ----
306 2023-05-12 15:36 archive1.zip
0 2023-05-12 15:31 dir1/
0 2023-05-12 15:31 dir2/
0 2023-05-12 15:31 test1.txt
--------- -------
306 4 files
Finally, let's extract the files!
Extract the contents of archive1.zip to a new directory, dir3. We will use the -d flag for this purpose. - #1
Extract the contents of archive2.zip to the current directory, testdir. - #2
[47 | testdir] $ mkdir dir3
[48 | testdir] $ unzip archive1.zip -d dir3 #1
Archive: archive1.zip
creating: dir3/dir1/
extracting: dir3/test1.txt
[49 | testdir] $ unzip archive2.zip #2
Archive: archive2.zip
replace archive1.zip? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
extracting: archive1.zip
extracting: test1.txt
[50 | testdir] $ ls dir3
dir1 test1.txt
Notice that in command #2, unzip is asking us if we want to replace an existing file in the directory. We also noticed that mv & cp didn't ask us before replacing existing files, just a while back
Since this behaviour isn't consistent across all commands, it's better to be a little bit careful when you're handling files & folders in Linux.
Using a package manager (apt)
What is a package manager?
A package manager is an utility which allows us to manage packages in Linux. It allows us to update, install & uninstall apps right from the terminal. There are many package managers available for us to use, like apt, pacman, dnf, etc.
Why apt and not something else?
Since most people start with Debian as their first Linux distribution, and Debian ships with apt as the package manager, we will use apt for this tutorial.
So how do we use apt?
With the theory out of the way, let's jump right into running some apt commands!
apt update -> Syncs the cloud package repository database with the locally stored one, and shows available updates, if any. - #1
apt upgrade -> Upgrade all packages which have an update available. - #2
apt search nano -> Search for the package nano in the repository. It returns all packages which have the string nano present in them. - #3
apt install nano -> Install the package nano. Use -y to directly install the package without asking for confirmation. - #4
Note that after running apt install, apt provides a detailed description of what additional dependencies are needed to run nano, and also specifies that they'll be installed automatically. It even suggests we install some packages that will enhance the functionality of the base package, nano. It's pretty informative, isn't it?
apt remove nano -> Remove the package nano from the system, leaving the configuration files untouched. - #5
apt autoremove -> Automatically remove packages that were installed as dependencies in the past, and are no longer needed. - #6
Note:- You need to prefix 'sudo' before all the commands (Ex. $ sudo apt update) because apt needs root access to modify packages installed in the system unless you're the root user in your system.
root@e16e355cbb51:/$ apt update #1
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
...
All packages are up to date.
root@e16e355cbb51:/$ apt upgrade #2
Reading package lists... Done
...
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
root@e16e355cbb51:/$ apt search nano #3
Sorting... Done
Full Text Search... Done
deepnano/stable 0.0+git20170813.e8a621e-3.1 amd64
alternative basecaller for MinION reads of genomic sequences
...
root@e16e355cbb51:/$ apt install nano #4
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
libgpm2 libncursesw6
Suggested packages:
gpm hunspell
The following NEW packages will be installed:
libgpm2 libncursesw6 nano
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 825 kB of archives.
After this operation, 3087 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
...
root@e16e355cbb51:/$ apt remove nano #5
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
libgpm2 libncursesw6
Use 'apt autoremove' to remove them.
The following packages will be REMOVED:
nano
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 2591 kB disk space will be freed.
Do you want to continue? [Y/n] y
...
root@e16e355cbb51:/$ apt autoremove #6
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
libgpm2 libncursesw6
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
After this operation, 497 kB disk space will be freed.
Do you want to continue? [Y/n] y
Working with text files on the terminal
Now that we've learnt the basics of adding/removing things in our directory, let's create some simple text files. Here are our objectives.
Since we already have the empty file 'test1.txt' in our directory, we shall attempt to add the line 'Hello, world!' to it, without using a text editor. - #1
Next, we'll add a second line 'I love using the Linux terminal!' using a text editor (I'll use nano for this one).
Then we'll display the contents of the file using 'cat'.
Finally, we shall attempt to create a simple Python file that prints 'Hello, world!' on the screen. We'll also learn how to run it directly in the terminal!
[51 | testdir] $ cat test1.txt #1
[52 | testdir] $ echo 'Hello, world!' >> test1.txt #2
[53 | testdir] $ cat test1.txt #3
Hello, world!
Looks like we've successfully added our first line to the file! Now, let's add the second line, using a text editor this time. The syntax is simple, just type in the name of the editor, and then the name of the file you want to edit.
[54 | testdir] $ nano test1.txt #1
All the next commands are specific to the 'nano' text editor, they won't work if you intend to use some other editor of your choice.
Add the 2nd line as you would, in something like notepad (use the keyboard for moving the cursor).
Save the file using Ctrl+O, then Enter.
Exit nano using Ctrl+X.
Now, let's verify the contents of the file using 'cat'. - #1
[55 | testdir] $ cat test1.txt #1
Hello, world!
I love using the Linux terminal!
Getting info about a file's contents: wc
The command 'wc' stands for Word Count in Linux. It can not only count words, but also the number of characters, bytes, lines, and more! The usual syntax is:
$ wc <flag> <file-name>
Let's take the file we just created, i.e. test1.txt, as an example. Here are some of the flags we can use:
wc -c test1.txt: Prints the byte count of the file. - #1
wc -l test1.txt: Prints the number of lines the file consists of. - #2
wc -m test1.txt: Prints the number of characters in the file. - #3
wc -w test1.txt: Prints the number of words in the file. - #4
[56 | testdir] $ wc -c test1.txt #1
14 test1.txt
[57 | testdir] $ wc -l test1.txt #2
1 test1.txt
[58 | testdir] $ wc -m test1.txt #3
14 test1.txt
[59 | testdir] $ wc -w test1.txt #4
2 test1.txt
This should be about enough to get you started on the Linux terminal. Keep learning!