Essential Linux commands

by Double Bastion - Updated October 27, 2022

Below you can find a list with the most frequently used commands on a Debian Linux system. Most of them will also work on other Linux distributions. These commands can be run in a terminal, on a laptop or desktop, but also on a remote VPS or dedicated server, while connected to it via SSH. When you run them, replace the strings in red with your own values.

The commands listed below are, in broad lines, all you need to know in order to start maintaining a Debian server (and more than enough to maintain a Debian laptop or desktop).

1. Connecting to a remote Linux server via SSH, changing the password, navigating the directory tree, etc.

➤ Connect to a remote Linux server via SSH

If you want to log in via SSH to a remote Linux server on the default port 22, run:

ssh username@123.123.123.123

where username is your username and 123.123.123.123 is the public IP of the server. After running this command, you will have to enter your password.

If you want to connect using a custom port for SSH connections, run:

ssh -p 5426 username@123.123.123.123

where 5426 is the custom SSH port.

➤ Change root password

While logged in as root run:

passwd

You will be asked to enter the new password twice.

➤ Change your password while logged in as a regular user
passwd
➤ Change any regular user’s password

While logged in as root run:

passwd username
➤ Log in as a different user
su username
➤ Log in as root if logged in as a regular user
su -
➤ Log out

If you are logged in to a remote Debian server via SSH using a terminal, to log out run:

exit

For example, if you are logged in as user john and you run exit, the uesr john will be logged out. However, if before being logged in as john you have been logged in as a different user, let’s say bill, after running exit as john, you will be logged in as bill again.

If you are logged in to a local laptop/desktop running Debian with a desktop environment, the easiest way to log out is by clicking on the Main Menu button > Log Out > Log Out.

➤ Restart a Debian system

While logged in as root run:

reboot
➤ Shut down a Debian system

While logged in as root run:

poweroff
cd /path/to/directory
cd ..
cd ~

or simply:

cd
➤ Get the machine’s hostname
hostname
➤ Check the current version of Debian
cat /etc/debian_version
➤ Check the version of the current Linux kernel
uname -r

2. Working with files and directories

➤ List all the files and directories in the current directory, excluding the hidden files and directories
ls
➤ List all the files and directories in the current directory, including the hidden files and directories
ls -a
➤ List all the files and directories in the current directory, including the hidden files and directories, with their permissions, ownership, sizes (in bytes) and the date of their last edit
ls -al

This command will list the size for both files and directories, but only the size of files will be accurate. The size will be listed in bytes, in the 5th column, just before the month of the last edit.

➤ List all the files and directories in a specific directory, including the hidden files and directories, with their permissions, ownership, sizes (in bytes) and the date of their last edit
ls -al /path/to/directory

Like before, this command will list the size for both files and directories, but only the size of files will be accurate. The size will be listed in bytes, in the 5th column, just before the month of the last edit. To list the size of all the files in human readable form (in KB, MB, GB, instead of bytes), run:

ls -alh /path/to/directory
➤ List the permissions, ownership and size of a specific file
ls -l /path/to/file

The size will be listed in bytes, in the 5th column, just before the month of the last edit. To list the size in human readable form (in KB, MB, GB, instead of bytes), run:

ls -lh /path/to/file
➤ List the size of a specific directory
du -sh /path/to/directoryname
➤ List the size of all the directories (excluding the hidden directories) inside a specific directory
du -sh /path/to/directory/*

This command will list in fact the size for both directories and files, but only the size of directories will be accurate.

➤ Open a file with nano for editing
nano /path/to/filename
➤ Save a file after editing it with nano

After you edit a file with nano, you can save it by pressing Ctrl + s.

If you have a file opened with nano and you press Ctrl + x, you will exit the file, but if the file hasn’t been saved, you will be first asked if you want to save it by pressing y. So, the fastest way to save a file that you have just edited with nano is to press Ctrl + x, then y.

➤ Create a file

If you just want to create an empty file run:

touch /path/to/filename

If you want to create a file and add content to it, run:

nano /path/to/filename

then write the content, then press Ctrl + x, then y to save the file and exit. In this way, you can use nano to create a new file. However, if you don’t add any content inside the new file opened with nano and you exit it, the file won’t be created.

➤ Search for a string in a file with nano

After you open the file with nano, press Ctrl + w, then write the string that you want to search for, then press Enter. The cursor will jump to the first occurrence of the string that you have searched for. (If the string isn’t found, you will see the message [ “searched string” not found ] at the bottom of the screen.) To see the next occurrence of the string that you have searched for, you can press Ctrl + w again, then Enter.

➤ Search for and replace a string in a file with nano

Open the file with nano /path/to/filename .
Press Ctrl + \ .
Enter your search string, then press Enter.
Enter your replacement string, then press Enter.
Press y repeatedly to replace each instance of the string, or press Shift + a to replace all instances.

➤ Open a file with line numbering, with nano
nano /path/to/filename -l
➤ Go to the last line of the current file opened with nano

Press Ctrl + w then v . (While keeping the Ctrl key pressed, first press w, then v)

➤ Go to the first line of the current file opened with nano

Press Alt + \ . (While keeping the Alt key pressed, press \)

➤ Select, copy, cut and paste text in a file opened with nano

Select text: Set the mark for selection by pressing Alt + a, then use the arrow keys to select the text.
Copy selection to the nano buffer: with the text selected, press Alt + 6 (the 6 key on the number row, not on the number pad).
Cut selected text: Ctrl + k .
Paste selection from the nano buffer into the current document, where the cursor is positioned:
Ctrl + u .

➤ Copy from the system’s clipboard into a file opened with nano

Select the text from any source (file, web page, etc.) and copy it to the system’s clipboard with Ctrl + c or by right-clicking and choosing the copy option from the right-click menu, then go to the file opened with nano, place the cursor where you want to insert the text and press Shift + Insert .

➤ Copy from a file opened with nano into another file

First exit the file opened with nano with Ctrl + x and display its content in the terminal with the cat command:

cat /path/to/file

Use your mouse to select the lines that you want to copy, from the output of the cat command. Then open the file that you want to insert the copied lines into, with nano /path/to/otherfile . Place the cursor where you want the copied lines to be pasted, then press Shift + Insert .

➤ Copy from different sources and paste into the terminal

Select the text that you want to copy from any source (file, web page, etc.) with your mouse, then click in the terminal with the middle mouse button (which is usually the wheel; in general, the mouse wheel can be both rotated and clicked). This will paste the text that you have just selected with your mouse. In general, you will want to paste a command, which means only one line of text.

Please note that if you are using Linux on your laptop/desktop, you will have 2 clipboards:

  • the X Window System’s clipboard, to which you can copy just by selecting content with your mouse; you can paste that content with the middle mouse button (the mouse wheel).

  • the clipboard of the desktop environment (MATE, KDE, GNOME, etc.), to which you can copy by selecting the text and then pressing Ctrl + c, or by selecting the content with your mouse, right-clicking and choosing Copy from the right-click menu. You can paste that content with Ctrl + v or by right-clicking and choosing Paste. (In a terminal, you cannot paste from the desktop environment’s clipboard with Ctrl + v ; you can only paste with the Paste option from the right-click menu.)
➤ Remove a file
rm /path/to/filename
➤ Remove a file securely (by overwriting it 3 times before deleting it)
shred -u /path/to/filename
➤ Create a directory in a specific location that already exists
mkdir /path/to/location/directoryname
➤ Create a directory and all the parent directories as needed (if the parent directories don’t exist, they will be created, if they already exist, they won’t be recreated)
mkdir -p /path/to/directory/to/be/created/directoryname
➤ Create multiple nested directories at once
mkdir -p /path/to/directory/{public,cache,log}

The command from above will create these 3 directories: /path/to/directory/public, /path/to/directory/cache and /path/to/directory/log.

➤ Remove a directory
rm -r /path/to/directoryname

-f can be added to force removal:

rm -rf /path/to/directoryname
➤ Copy a file to a new location
cp /path/to/filename /new/path
➤ Copy a file to a new location under a different name
cp /path/to/filename /new/path/newfilename
➤ Copy a directory with all its content, to a new location
cp -r /path/to/directoryname /new/path
➤ Copy a directory with all its content, to a new location, under a different name
cp -r /path/to/directoryname /new/path/newdirectoryname
➤ Copy a directory preserving the permissions, ownership and timestamps of all the files and directories inside it
cp -rp /path/to/directoryname /new/path/to/newlocation
➤ Copy all the files and directories, except the hidden files and directories, from a directory to a different directory
cp -r /path/to/directoryname/* /new/path/to/newlocation
➤ Copy all the files and directories, including the hidden files and directories, from a directory to a different directory
cp -r /path/to/directoryname/{.,}* /new/path/to/newlocation

The hidden files and directories are those whose name starts with a dot, like .bashrc or .config .

The command from above will generate the following message, which you can ignore:

cp: will not create hard link '/path/to/directoryname' to directory '/new/path/to/newlocation/.'
➤ Copy all the files and directories, except the hidden files and directories, from the current directory to the parent directory
cp -r * ../
➤ Copy all the files and directories, including the hidden files and directories, from the current directory to the parent directory
cp -r /path/to/currentdirectory/{.,}* ../

The command from above will generate the following message, which you can ignore:

cp: '/path/to/currentdirectory/..' and '../' are the same file
➤ Move a file to a new location
mv /path/to/filename /new/path
➤ Move a file to a new location, under a different name
mv /path/to/filename /new/path/newfilename
➤ Rename a file
mv /path/to/filename /path/to/newfilename

or, if you are already in the parent directory of the file that you want to rename, run:

mv filename newfilename
➤ Move a directory with all its content, to a new location
mv /path/to/directoryname /new/path
➤ Move a directory with all its content, to a new location, under a different name
mv /path/to/directoryname /new/path/newdirectoryname
➤ Move all the files and directories, except the hidden files and directories, from a directory to a different directory
mv /path/to/directoryname/* /new/path/to/newlocation
➤ Move all the files and directories, including the hidden files and directories, from a directory to a different directory
mv /path/to/directoryname/{.,}* /new/path/to/newlocation

The command from above will generate the following message, which you can ignore:

mv: cannot move '/path/to/directoryname/.' to '/new/path/to/newlocation/.': Device or resource busy
mv: cannot move '/path/to/directoryname/..' to '/new/path/to/newlocation/..': Device or resource busy
➤ Move all the files and directories, including the hidden files and directories, from the current directory, to the parent directory
cp -r /path/to/currentdirectory/{.,}* ../

The command from above will generate the following message, which you can ingore:

mv: cannot move '/path/to/currentdirectory/.' to '../.': Device or resource busy
mv: cannot move '/path/to/currentdirectory/..' to '../..': Device or resource busy
➤ Rename a directory
mv /path/to/directoryname /path/to/newdirectoryname

or, if you are already in the parent directory of the directory that you want to rename, run:

mv directory newdirectoryname
➤ Remove all the files and directories, except the hidden files and directories, from a specific directory
rm -r /path/to/directoryname/*
➤ Remove all the files and directories, including the hidden files and directories, from a specific directory
rm -r /path/to/directoryname/{.,}*

The command from above will generate the following message, which you can ignore:

rm: refusing to remove '.' or '..' directory: skipping '/path/to/directoryname/.'
rm: refusing to remove '.' or '..' directory: skipping '/path/to/directoryname/..'
ln -s /path/to/file/to/be/linked /location/of/link

The command from above will create the symbolic link /location/of/link/linked, which will point to the /path/to/file/to/be/linked file.

ln -s /path/to/file/to/be/linked /location/of/link/newname
ln -s /path/to/directory /location/of/link

The command from above will create the symbolic link /location/of/link/directory, which will point to the /path/to/directory directory.

➤ Display the content of a file
cat /path/to/file
➤ Append the content of file2 to the content of file1
cat file2 >> file1
➤ Combine the content of file1, file2 and file3, to produce file4
cat file1 file2 file3 > file4

In the result file, file4, the content of file1 will be included first, then the content of file2, then the content of file3.

➤ Find a file
find /path/to/directory -name 'filename'

The command from above searches for file filename in the /path/to/directory directory.

find /path/to/directory -iname 'prof*'

The command from above searches for files beginning with ‘prof’ in the /path/to/directory directory, irrespective of letter case.

➤ Find a directory
find /path/to/directory -type d -name 'dirname'

The command from above searches for the dirname directory in the /path/to/directory directory and all its subdirectories.

➤ Change the user and group ownership of a file
chown john:ftpuser /path/to/filename

The command from above will make the user john and the group ftpuser owners of the filename file.

➤ Change the user and group ownership of a directory
chown john:ftpuser /path/to/directoryname
➤ Change the user and group ownership of a directory and of all the files and subdirectories inside it
chown -R john:ftpuser /path/to/directoryname

The command from above will make the user john and the group ftpuser owners of the directoryname directory, and of all the files and subdirectories inside it.

➤ Change file permissions
chmod 644 /path/to/filename

The command from above will set the 644 permissions for the filename file.

The numeric code of the permissions is made up of three digits:

  • the first digit indicates the permissions given to the user who owns the file
  • the second digit indicates the permissions given to the group who owns the file
  • the third digit indicates the permissions given to all the other users

The numeric codes for the different combinations of the read, write and execute permissions are the following:

0 --- indicates no permissions
1 --x indicates execute permissions
2 -w- indicates write permissions
3 -wx indicates write and execute permissions
4 r-- indicates read permissions
5 r-x indicates read and execute permissions
6 rw- indicates read and write permissions
7 rwx indicates read, write, and execute permissions

644 means that the user who owns the file has only read and write permissions, the group who owns the file has read only permission and other users have read only permission.

If you have a file called bscript, owned by the user clamav and by the group postfix and you want to give the user clamav read, write and execute permissions on this file, you want to give the group postfix read and execute permissions and you want to give other users read and execute permissions, you will run:

chmod 755 /path/to/bscript

Then, you can check the new file permissions by running:

ls -l /path/to/bscript

The output will be similar to this:

-rwxr-xr-x 1 clamav postfix 180 May 11 06:36 /path/to/bscript

To check the permissions of a directory, run:

ls -ld /path/to/directory

Permissions can be also changed by using the symbolic notation. The user who owns the file is represented by the letter u, the group by g, other users by o, all users by a. The read permission is represented by the letter r, write permission by w and execute permission by x. Therefore, the 755 permissions set in the example from above can be also set by running:

chmod u=rwx,g=rx,o=rx /path/to/bscript

To give read permissions to everyone on the filename file, you would run:

chmod a=r /path/to/filename

or

chmod a+r /path/to/filename

To make the file readable and writable by the group and others and let the permissions for the user who owns the file unchanged, you would run:

chmod go=rw /path/to/filename

or

chmod go+rw /path/to/filename

To make a file executable by the user who owns the file, you would run:

chmod u=x /path/to/filename

or

chmod u+x /path/to/filename

To deny execute permissions to the group who owns the file, you could run:

chmod g-x /path/to/filename

Please note that the symbolic links will always have the 777 permissions. If you try to change the permissions of a symbolic link with the chmod command, only the permissions of the pointed-to file will be changed, while the permissions of the symbolic link will remain 777.

➤ Change directory permissions

Directory permissions can be changed exactly as file permissions. For example, to give the user who owns the directory directoryname read, write and execute permissions, to give the group read and execute permissions and to give other users read and execute permissions, you will run:

chmod 755 /path/to/directoryname

When you will check directory permissions with the ls -ld /path/to/directoryname command, the result will be similar to this:

drwxr-xr-x  3 root root 4096 Apr 20 23:13 directoryname

The letter d from the beginning of the row from above indicates that directoryname is a directory and not a file.

You can also change the permissions for a directory ‘recursively’ by adding the -R option. This will change permissions for the directory itself and for all the files and subdirectories inside it:

chmod -R 755 /path/to/directoryname

If you run chmod recursively on a directory, like above, it will ignore the symbolic links encountered inside that directory.

Please note that when used for directories, the read, write and execute permissions have a different meaning than for files:

  • read (r) permission: the user having this permission on the directory can list the names of all the files and directories inside that directory.

  • write (w) permission: the user having this permission on the directory can create, rename and delete files or directories inside that directory. Please note that to be able to create, rename and delete files or directories inside that directory, the user must also have execute permission on that directory.

  • execute (x) permission: the user having this permission can navigate to that directory with the cd /path/to/directoryname command, making that directory the current working directory and can access (read, write, execute) the files/directories inside that directory. Therefore, in order to read/write/execute a file inside a directory, the user needs to have read/write/execute permission on that file, but also execute permission on the parent directory of that file.
➤ Change permissions only for the subdirectories of a directory
find /path/to/directoryname -type d -exec chmod 750 {} +

The command from above will set the 750 permissions for all the subdirectories of the directoryname directory, but will leave the file permissions unchanged for all the files inside the directoryname directory and inside all its subdirectories.

➤ Change permissions only for the files inside a directory and inside its subdirectories
find /path/to/directoryname -type f -exec chmod 660 {} +

The command from above will set the 660 permissions for all the files inside the directoryname directory and inside its subdirectories, but will leave the directory permissions unchanged for the directoryname directory and for all its subdirectories.

The setUID, setGID and sticky bit

On a Linux system, the ownership of a file depends on the user ID (UID) and group ID (GID) of the user who creates it. Similarly, when a process is launched, it runs with the UID and the GID of the user who launches it. To accommodate special situations, this default behavior can be modified by setting the setUID bit, the setGID bit or the sticky bit. These special permissions should be used cautiously only when necessary, because using them inappropriately can cause serious security vulnerabilities.


The setUID bit

The setUID bit is used only for executable files. It’s not used for directories. When the setUID bit is set for an executable file, it indicates that the user who launches the executable will run it with the permissions of the owner of that file and not with his own permissions. For example, if an executable has the setUID bit set on it, and it’s owned by root, when launched by a regular user, it will run with root privileges. This implies security risks if not used correctly.

An example of a file with the setUID permission set is /usr/bin/passwd, the utility used to change the user password. If you run:

ls -l /usr/bin/passwd

the output will be similar to this:

-rwsr-xr-x 1 root root 63736 Jul 27  2018 /usr/bin/passwd

As you can see, instead of the x of the executable bit for the user who owns the /usr/bin/passwd file, there is an s. That s indicates that the setUID bit is set for the /usr/bin/passwd executable, so that it will run with root privileges, even if launced by a regular user.

To set the setUID bit for an executable file, prepend the permissions number with 4. For example, to set the setUID bit for the /path/to/file file, you can run a command like this:

chmod 4755 /path/to/file

Please note that the command from above will remove the setGID bit, if the file has the setGID bit set.

You can also set the setUID bit using the symbolic notation, like this:

chmod u+s /path/to/file

When you set the setUID bit with the chmod u+s /path/to/file command, if the file already has the setGID bit set, the setGID bit will not be removed, so, the file will end up having both the setGID bit and the setUID bit set.

To remove the setUID bit, run:

chmod u-s /path/to/file

You can also remove the setUID bit (along with the setGID bit, if it is set), by prepending 00 in front of the permissions number, like this:

chmod 00755 /path/to/file

Please note that to set the setUID bit correctly, the user who owns the file has to have execute permission on that file. If, for example, the /path/to/filename file has 654 permissions, which means that that user who owns the file doesn’t have execute permission, and you set the setUID bit on it, when you check its permissions with ls -l /path/to/filename, you will see something similar to this:

-rwSr-xr-- 1 root root 5624 May 21  2021 /path/to/filename

The capital letter S indicates that the setUID bit is set, but the user who owns the file doesn’t have execute permission on it, therefore, it shows an inconsistency that has to be corrected. You can solve the problem by giving the user who owns the file execute permission (chmod 754 /path/to/filename in this example).


The setGID bit

The setGID bit can be used for both files and directories.

If an executable file has the setGID bit set, when a user launches that executable, it will run with the permissions of the group who owns the executable and not with the permissions of the group of the user who launches the executable.

If you run:

ls -l /usr/bin/crontab

the output will be similar to this:

-rwxr-sr-x 1 root crontab 43568 Oct 11  2019 /usr/bin/crontab

As you can see, instead of the x of the executable bit for the group owner of the /usr/bin/crontab file, there is an s, indicating that the setGID bit is set.

If a directory has the setGID bit set, when a user creates files inside that directory, the group owner of the newly created files will be the group of the parent directory, and not the group of the user who creates the files.

To set the setGID bit for a file or directory, prepend 2 to the permissions number for that file or directory, like this:

chmod 2755 /path/to/file-or-directory

Please note that if the command from above is applied to a file and that file has the setUID bit set, the command will set the setGID bit, but it will remove the setUID bit. If the command is applied to a directory and that directory has the sticky bit set, the command will set the setGID bit, but it will remove the sticky bit.

You can also use the symbolic notation to set the setGID bit, like so:

chmod g+s /path/to/file-or-directory

If you set the setGID bit with the chmod g+s /path/to/file-or-directory command on a file, and that file has the setUID bit set, the setUID bit will not be removed, so, the file will end up having both the setUID bit and the setGID bit set. If you apply the command to a directory and that directory has the sticky bit set, the sticky bit will not be removed, so, the directory will end up having both the sticky bit and the setGID bit set.

To remove the setGID bit, run:

chmod g-s /path/to/file-or-directory

You can also remove the setGID bit (along with the setUID bit and the sticky bit, if they are set), by prepending 00 in front of the permissions number, like this:

chmod 00755 /path/to/file-or-directory

Please note that to correctly set the setGID bit on a file or directory, that file or directory has to be executable by the group that owns it.


The sticky bit

The sticky bit is used only for directories. When a directory has the sticky bit set, the files inside that directory can be deleted or renamed only by the user who owns the files, by the user who owns the directory, or by root. A typical directory with the sticky bit set is the /tmp directory, which has to be writable by all the users on the system. To prevent one user from removing the files of another user, the sticky bit is set for /tmp. If you run:

ls -ld /tmp

you will see the permissions for the /tmp directory, which will look like this:

drwxrwxrwt  11 root root  4096 May 15 07:37 tmp

You can notice that instead of the x of the executable bit for other users, there is a t. The letter t indicates that the sticky bit is set for the /tmp directory.

To set the sticky bit for a directory, prepend 1 to the permissions number, like this:

chmod 1755 /path/to/directory

Please note that if you set the sticky bit on a directory with the command from above, if that directory has the setGID bit set, the command will not remove the setGID bit, so, the directory will end up having both the sticky bit and the setGID bit set. (As mentioned before, the opposite is not true: if you set the setGID bit on a directory that already has the sticky bit set, the setGID bit will be set but the sticky bit will be removed.)

You can also use the symbolic notation to set the sticky bit:

chmod o+t /path/to/directory

To remove the sticky bit, run:

chmod o-t /path/to/directory

You can also remove the sticky bit (along with the setGID bit, if it is set), by prepending 00 in front of the permissions number, like this:

chmod 00755 /path/to/directory

To set the sticky bit correctly, the directory has to be executable by other users. If you set the sticky bit on a directory that is not executable by other users, when you will list the permissions for that directory, you will see the capital letter T instead of the lower case t. This will indicate that the sticky bit is set, but the directory is not executable by other users. To correct this problem you have to make the directory executable by other users.

➤ Find a user’s UID
id -u username
➤ Find a user’s GID
id -g username
➤ Find the UID, GID and all the groups associated with a user
id username
➤ The umask command

On a Linux system, all new files and directories are created with a default set of permissions. The umask command allows you to view and change the default permissions for newly created files and directories. More specifically, the umask command can be used to change the file mode creation mask, which will determine the permissions for the newly created filed and directories.

In Linux, the default permissions for regular files are 666 and for directories 777. To understand how the umask value determines the permissions for the newly created files and directories, you have to subtract the umask value from the default permissions for files and directories. For example, if the umask value is 022, then any new files will be created by default with the permissions 644 (666 – 022) and any new directories will be created by default with the permissions 755 (777 – 022).

It’s important to note that the umask has a default system-wide value, which in Debian is set in the /lib/x86_64-linux-gnu/security/pam_umask.so binary file and can be overwritten in the /etc/profile file. This default system-wide umask value can be also overwritten at the level of each user, in the /home/username/.bashrc file of each user. In addition to this, a specific umask value can be manually set in the terminal, by running umask value, where value is the 3 digits number of the new umask. The umask that is manually set in the terminal will only affect the current shell session. If you log out and then start a new shell session, the umask that you set manually in the previous session will be lost and the default umask will be applied to newly created files and directories.

To view the current umask, run:

umask

If you haven’t changed the default umask before running this command, its output will be 0022. The first digit specifies the special permissions (the setUID, setGID or the sticky bit); 0 indicates that no special permissions are set in the umask. Therefore, the default umask is effectively 022, which means that by default, any new file will have 644 permissions (666 – 022 = 644) and any new directory will have 755 permissions (777 – 022 = 755). If you want to change the default umask in order to create new files and directories with different permissions, let’s say 750 for directories and 640 for files, you can change the umask in the terminal by running:

umask 027

(For directories 777 – 027 = 750, but for files 666 – 027 = 639. In this case, the resulting permissions for files will be 640, because to calculate the permissions for files, any digit in the umask that is greater than 6 will be considered 6.)

If you want to make the umask change permanent only for a specific user called username, you have to edit the /home/username/.bashrc file:

nano /home/username/.bashrc

At the beginning of the file, add this line:

umask 027

(Replace 027 with your desired umask. If the line is already present in the file, change it to reflect your new umask value.) For the change to take effect, the username user has to log out and log in again.

If you want to make the umask change permanent system-wide, for all users, edit the /etc/profile file:

nano /etc/profile

At the beginning of the file, add this line:

umask 027

(Replace 027 with your desired umask. If the line is already present in the file, change it to reflect your new umask value.) For the change to take effect, the users have to log out and log in again.

The umask value command is often used inside shell scripts to change the default umask during certain operations, in order to create new files or directories with different permissions than the default ones. If the default umask is changed in a script, it will be changed only for the operations specified in the script. After the script has been run, the system will use the default umask again.

➤ Archive/unarchive and compress/decompress files and directories

Although they are often performed together, archiving and compressing are two different actions.

Archiving means to save one or multiple files or directories in a single archive file, which can be then used to restore the original files or directories. Archiving is usually done with the command:

tar cf archivename.tar file_or_directory_name

The resulting archivename.tar file is often called a tar ball. However, in practice, archiving is almost always done together with the compression of the archive file, to reduce the space needed for storage. Therefore, archiving and compressing are usually done in one command, as presented further down below. Yet, it’s important to understand that they are two different actions.

If you just want to compress a file or a directory, you can use a specific command for each major compressed file format, like this:

zip compressedfile.zip file_name (for files)
zip compressedfiles.zip file_name1 file_name2 file_name3 (for multiple files)
zip -r compresseddirectory.zip directory_name (for directories)
zip -r compresseddirectories.zip directory_name1 directory_name2 directory_name3 (for multiple directories)

gzip file_name (for files; the resulting file will have the gz termination)
gzip file_name1 file_name2 file_name3 (for multiple files)
gzip -r directory_name (for directories; gzip will enter the directory_name directory and compress all the files that it finds there in their location)
gzip -r directory_name1 directory_name2 directory_name3 (for multiple directories)

bzip2 file_name (for files; the resulting file will have the bz2 termination)
bzip2 file_name1 file_name2 file_name3 (for multiple files)
bzip2 /path/to/directory_name/* (to compress all the files inside the directory_name directory)

xz file_name (for files; the resulting file will have the xz termination)
xz file_name1 file_name2 file_name3 (for multiple files)
xz /path/to/directory_name/* (to compress all the files inside the directory_name directory)

If you want to both archive a file/directory and compress the archive, the easiest way is to first navigate to the directory where the file or directory to be compressed is located:

cd /path/to/directory

then use the tar command to archive and compress the file or directory, like this:

tar czf archivename.tar.gz file_or_directory_name
tar cjf archivename.tar.bz2 file_or_directory_name
tar cJf archivename.tar.xz file_or_directory_name

Therefore, to use gzip compression to create a tar.gz compressed archive file, you have to use the tar command with the czf options. This type of compression is generally fast, but doesn’t offer the highest compression ratio.

To use bzip2 compression to create a tar.bz2 compressed archive file, you have to use the tar command with the cjf options. This type of compression provides a slightly better compression ratio than gzip, but uses a little more CPU and RAM resources, so, it’s usually slower.

To use xz compression to create a tar.xz compressed archive file, you have to use the tar command with the cJf options. This type of compression offers the best compression ratio, but is the most expensive in terms of CPU and RAM usage, so, it is in general slower than the other two types of compression.

If you want to archive and compress multiple files and/or directories, you can add their name one after the other, separated by space, like this:

tar czf archivename.tar.gz file1 file2 directory1 directory2 directory3

If you want to create the archive in a different directory than the current directory, or the file or directory to be compressed is located in a different directory than the current directory, you can include the path to the resulting archive, or the path to the file or directory to be compressed, like this:

tar czf /path/to/archivename.tar.gz /path/to/file_or_directory_name

Please note that if you include the path to the file or directory to be compressed, like above, when you will decompress the resulting archive, you will find the decompressed file or directory inside the path/to directory that will be automatically created during decompression in the current directory.

To decompress files or directories that have been only compressed, run:

unzip filename.zip

gunzip filename.gz

bunzip2 filename.bz2

unxz filename.xz

To unzip to a specific directory, first create that directory, then run:

unzip filename.zip -d /path/to/directory

This command works with unzip but not with gunzip, bunzip2 or unxz.

To decompress and unarchive files or directories that have been both archived and compressed, run:

tar xf archivename.tar.gz
tar xf archivename.tar.bz2
tar xf archivename.tar.xz

Please note that although you can specify the type of decompression to be used when running the commands from above (by including the z, j or J options like this: tar xzf archivename.tar.gz , tar xjf archivename.tar.bz2 or tar xJf archivename.tar.xz), this is not really necessary, because tar inspects the compressed file and automatically detects the type of compression used. The dash (-) that can be added before the options (for example: tar -xf archivename.tar.gz) is not really needed either. It’s preferable to keep the commands as simple as possible, so, you can run them without prepending the options with the dash (-) and without specifying the type of compression.

To decompress and unarchive to a target directory, run:

tar xf archivename.tar.gz -C /path/to/target/directory

If you want to see what the tar command is doing, you can always use the ‘verbose mode’, by adding the v option, like this:

tar xvf archivename.tar.gz

You can list the content of a compressed archive with:

tar tf archivename.tar.gz
➤ Set up a cron job

The most commonly used method to automate various operations on a Linux system is to use cron jobs. cron is a time-based job scheduler.

The most commonly used way to set up cron jobs is to add cron job definitions to the crontab file of each user. The users’ crontab files are located in the /var/spool/cron/crontabs directory, each bearing the name of the user to which it belongs. However, they shouldn’t be edited directly. Instead, they should be edited using the crontab -e command while logged in as the user for which you want the cron job to be set up. For cron jobs with system-wide scope you should run the crontab -e command while logged in as root. The cron jobs added by regular users can also affect the whole system, but they are usually associated with activities and files belonging to those non-root users.

When you run the crontab -e command, the crontab file of the logged in user will open, and you can edit it like any regular file. A cron job definition has the following structure:

Cron job definition:
.---------------- minute of the hour (0 - 59)
|  .------------- hour of the day (0 - 23)
|  |  .---------- day of the month (1 - 31)
|  |  |  .------- month of the year (1 - 12) OR jan, feb, mar, apr, may ...
|  |  |  |  .---- day of the week (0 - 6) (Sunday = 0 or 7) OR sun, mon ...
|  |  |  |  |
*  *  *  *  * command_to_be_executed

For example, to update the ClamAV antivirus every day at 3:47 AM, you will enter the following cron job definition:

47 3 * * * /usr/bin/freshclam --quiet

After you enter the cron job definition, you can save the crontab file like any regular file and from that moment on, the cron job will be run automatically, with the frequency that you specified. Other examples of cron jobs are listed below.

Run a command every 30 minutes:

*/30 * * * * command_to_be_executed

Run a command every 3 days, at 2:18 AM:

18 2 */3 * * command_to_be_executed

Run a command every 8 hours, at 5 minutes past:

5 */8 * * * command_to_be_executed

Run a command every Monday, at 3:16 AM:

16 3 * * 1 command_to_be_executed

Run a command on the third day of every month, at 4:52 AM:

52 4 3 * * command_to_be_executed

Run a command at 1:26 AM every 30 days:

26 1 */30 * * command_to_be_executed

Run a command at 3:14 AM, on the second day of January, April, July and October

14 3 2 1,4,7,10 * command_to_be_executed

Another way to set up a cron job is to include it in a separate file saved in the /etc/cron.d directory, or to enter it at the bottom of the /etc/crontab file. When using one of these two methods, you will have to add the name of the user before the actual command, like this:

* * * * * username command_to_be_executed

You can also automate operations by including them in scripts that you can save inside the /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly or /etc/cron.monhtly directory, depending on the frequency with which you want to run the scripts. To find what is the exact moment when a script placed inside the mentioned directories will be run, you can take a look to the /etc/crontab file. It will show the following moments for running the scripts located in the hourly, daily, weekly and monthly cron jobs directories:

17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

Before running the crontab -e command, it’s recommended to check your spelling twice, because if you press the r key instead of e (the two keys are located next to each other on regular keyboards), and you run crontab -r instead of crontab -e, the crontab -r command will remove all the content of your crontab file in a fraction of a second, without asking you if you want to delete that content. So, you will loose all your cron job definitions and you will have to set up all your cron jobs again.

3. Managing users and groups

➤ Add user tom with shell access and /home/tom as home folder
adduser tom
➤ Add user tom without shell access, with /path/to/dir as home directory
adduser --shell /bin/false --home /path/to/dir tom

If the option --home /path/to/dir is absent, the home directory /home/tom will be created by default for the user tom.

➤ Add user tom without shell access and without a home directory
adduser --shell /bin/false --no-create-home tom
➤ Add user tom as system user without shell access and without a home directory
adduser --system --shell /bin/false --no-create-home tom

--no-create-home means “do not create the home directory, even if it doesn’t exist”.

‘System users’ versus ‘regular users’

When creating a user to run a daemon, a service or other software, you should create a ‘system user’ rather than a ‘regular user’ which is generally created for a person to log in and interact with the server. System users will have smaller numbers as user IDs (typically below 999) as opposed to regular users who have larger numbers as user IDs (typically above 1000). ‘System users’ will not have aging information in the /etc/shadow file.

➤ Add a system group called bill, with 12 as group ID (GID)
addgroup --system --gid 12 bill
➤ Add a user with the adduser command

Add a system user called bill, with /var/cache/bill as home directory, with 6 as user ID (UID), in group bill, with no shell access

adduser --system --home /var/cache/bill --uid 6 --ingroup bill --shell /bin/false bill
➤ Add a user with the useradd command
useradd -r -u 150 -g mail -d /var/vmail -s /bin/false -c "Virtual maildir handler" vmail

-r create new user as system user
-u 150 set the user ID (UID) as 150
-g mail add the new user to the group mail
-d /var/vmail set /var/vmail as home directory for the new user
-s /bin/false add a user without shell access
-c add a comment, like a short description of the new user

When creating a new user with the useradd command without specifying the group name or the group ID, by default, the useradd command creates a group with the same name as the username, and the same group ID (GID) as the user ID (UID). When the home directory is not specified, useradd doesn’t create a home directory.

➤ Create a new group
addgroup groupname
➤ Delete a group
delgroup groupname
➤ Add user tom to group groupname
adduser tom groupname
➤ Remove user tom from group groupname
deluser tom groupname
➤ Give user tom shell access
usermod -s /bin/bash tom
➤ Disable shell access for user tom
usermod -s /bin/false tom
➤ Delete only the user account from a machine
userdel username

The disadvantage of the command from above is that it only deletes the user’s login details but not his home directory or his files.

➤ Delete the user account and his home directory and mail spool from a machine
userdel -r username

The -r option removes the user’s home directory with all its content and the user’s mail spool.


The two commands from above will not delete all the files owned by the user, which can be scattered in many different locations. With the deluser command you can delete the user account and all the files owned by the user.

➤ Delete only the user account with deluser
deluser username
➤ Delete the user account with deluser, even if the user is logged in
deluser -force username
➤ Delete the user account along with his home directory and his mail spool
deluser -remove-home username
➤ Delete the user account together with his home directory and along with all the files owned by that user, which can be located in different places that you are not aware of
deluser -remove-all-files username
➤ Delete a user account and take a backup of all his files to a directory, for future use
deluser -backup-to /path/to/directory username
➤ Change the home directory of a user
usermod -m -d /path/to/newhome username

usermod is the command to edit an existing user

-m (abbreviation for --move-home) will move the content from the user’s current directory to the new directory, but only if the new directory doesn’t exist.

-d (abbreviation for --home) will change the user’s home directory.

➤ Find groups of a user
groups username
➤ List all members of a group
grep groupname /etc/group
➤ Find all the directories and files belonging to the group groupname
find / -group groupname
➤ List all the users on the system
cat /etc/passwd
➤ Find the user under which a service runs
ps aux | grep servicename
➤ Add a non-administrative (regular) user to the sudo group

Install sudo:

apt-get install sudo

Then run:

visudo

to open the /etc/sudoers file for editing. Right below this line:

root    ALL=(ALL:ALL) ALL

add the following line:

username ALL=(ALL:ALL) ALL

4. Working with software packages

➤ Update the list of software repositories

First make a copy of the original /etc/apt/sources.list file:

cp /etc/apt/sources.list /etc/apt/sources.list_orig

Then, open the /etc/apt/sources.list file for editing:

nano /etc/apt/sources.list

Change or add software repository URLs.

Please note that software sources can be also included in files stored in the /etc/apt/sources.list.d directory. However, you can include all the repository URLs in the /etc/apt/sources.list file, to have them all in one place.

➤ Update the package lists
apt-get update
➤ Upgrade all existing packages without installing new packages or removing installed packages
apt-get upgrade
➤ Upgrade all existing packages and install new packages or remove old packages if there are dependencies that require this
apt-get dist-upgrade
➤ Update the package lists and upgrade all the packages with new versions, in one command
apt-get update && apt-get upgrade -y

The -y option is added to automatically answer ‘yes’ when asked if you want to upgrade packages to their latest version.

➤ Search for packages available for installation in the configured repositories
apt-cache search packagename

This command will search for package names identical or similar to packagename, in the software packages names and their long description.

➤ List dependencies of a package
apt-cache showpkg package_name

package_name has to be the exact name of the software package.

➤ Install a software package
apt-get install package_name
➤ Install multiple software packages
apt-get install package1 package2 package3
➤ Uninstall a software package but don’t delete its configuration files
apt-get remove package_name
➤ Uninstall a software package and delete its configuration files
apt-get purge package_name
➤ Remove all the packages that were installed by other packages and are no longer needed
apt-get autoremove
➤ List all the packages installed on the system
dpkg --get-selections
➤ Check if a package is installed
dpkg --get-selections | grep packagename

If this command gives no output, it means that the packagename package is not installed. If the output is similar to the following:

packagename                     install

it means that the packagename package is installed.

➤ List all the loaded units that the systemd init system is managing
systemctl

To exit the list view, press the q key.

➤ List all the services that are in failed state
systemctl --failed
➤ Check the status of a service
systemctl status servicename
➤ Configure a service to start when the system boots
systemctl enable servicename
➤ Configure a service not to start when the system boots
systemctl disable servicename
➤ Check if a service is configured to start when the system boots
systemctl is-enabled servicename
➤ Start a service
systemctl start servicename
➤ Stop a service
systemctl stop servicename
➤ Restart a service
systemctl restart servicename
➤ Reload a service
systemctl reload servicename
➤ Kill a service that refuses to stop
systemctl kill servicename
➤ List all the processes running on the system with their PID, users, etc.
top

To exit the top output view, press the q key.

➤ List all the processes running on the system and a graph with the real-time total CPU and RAM usage

First install htop with apt-get install htop, then run:

htop

To exit the htop output view, press the q key.

➤ Order all the processes running on the system after the RAM or CPU usage

Run:

htop

then press F6 (SortBy) and use the arrow keys to select PERCENT MEM or PERCENT CPU and press Enter.

➤ Reload the systemd daemon after changing a service file (like the files ending in .service located in the /lib/systemd/system directory)
systemctl daemon-reload
➤ Display all the active network interfaces and their status

First install net-tools with apt-get install net-tools, then run:

ifconfig

Instead of the ifconfig command you can also use:

ip a

The output of the two commands from above will show among other things the name of the active network interfaces (like eth0, ens3, etc.) and the IPv4 and IPv6 addresses. The IPv4 address is the one listed right after the term inet and the IPv6 address is the one listed right after the term inet6 and is followed by scopeid 0x0<global> or scope global.

➤ Find the route taken by data packets to the host of a website
traceroute www.example.com

If the website has IPv6 connectivity, you can also see the route to its host using the IPv6 protocol, with:

traceroute6 www.example.com

Please note that you can use the traceroute command to find the IP of a website, since the first line of the output of this command will look like this:

traceroute to www.example.com (123.123.123.123), 30 hops max, 60 byte packets

where 123.123.123.123 will be the IPv4 address of the server hosting the www.example.com website. You can also use the traceroute6 command to find the IPv6 address (if the website has IPv6 connectivity).

➤ Check if a website’s host is reachable using the ping command
ping www.example.com

The ping command sends ICMP echo requests and waits for responses. If the connection to the machine that hosts the www.example.com website is established, you will receive an echo reply for every request. For example, if you ping www.fsf.org, the result showing a successful connection will look like this:

ping www.fsf.org
PING www.fsf.org(www.fsf.org (2001:470:142:4::a)) 56 data bytes
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=1 ttl=53 time=15.6 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=2 ttl=53 time=14.0 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=3 ttl=53 time=13.7 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=4 ttl=53 time=14.0 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=5 ttl=53 time=14.0 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=6 ttl=53 time=14.1 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=7 ttl=53 time=14.2 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=8 ttl=53 time=14.1 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=9 ttl=53 time=14.4 ms
64 bytes from www.fsf.org (2001:470:142:4::a): icmp_seq=10 ttl=53 time=13.9 ms

Each row of the output contains the amount of time it takes for every packet to reach its destination and return.

To stop the ping command, press Ctrl + c . When you stop the ping command, it will print a few lines with statistics, that will show the total number of packet sent, received, if there were any lost packets, etc.:

--- www.fsf.org ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 21ms
rtt min/avg/max/mdev = 13.738/14.212/15.610/0.496 ms

If you want to check if a host is reachable over IPv6, use the ping6 command like this:

ping6 www.example.com

To limit the number of requests, run the ping command like this:

ping -c5 www.example.com

The -c5 option tells the ping command to stop after 5 requests.

If the connection to the website’s host can’t be established due to various network problems, you will see a specific message. The most common messages are:

  • Request timed out – the ping command timed out because there was no reply from the host. This can indicate very high network traffic, failure of the request packet filtering, router errors, or that the destination host is down or disconnected from the network.

  • Unknown host – this message means that the IP address of the host that you are pinging cannot be resolved. This can indicate problems with the DNS servers, or that the destination host is down or disconnected from the network.

  • Destination host unreachable – this can indicate that the host that you are trying to ping is down or is not connected to the network, or that there is a router issue somewhere between your machine and the destination host.

  • Hardware error – this is usually related to a physical problem on the laptop’s/desktop’s network card. It can indicate that your network card is not functioning, is disabled or you have unplugged the Ethernet cable.

  • TTL Expired in Transit – this usually indicates a routing issue on the network.

If you try to ping a domain name that is not registered, you will see the message: Name or service not known .

Please note that instead of the website’s domain, you can ping the IP address of the machine that hosts the website, if you know it.

➤ Find what services listen on what TCP ports
netstat -tlpn
➤ Find what services listen on what TCP and UDP ports
netstat -tulpn
➤ Find what TCP and UDP port(s) a specific service listens on
netstat -tulpn | grep servicename

For example, to find what ports the mysql service listens on, run:

netstat -tulpn | grep mysql
➤ Find a word or group of words in all the files located in a directory
rgrep wordtofind /path/to/directory

This command will look for the word wordtofind in all the files located inside the /path/to/directory directory and its subdirectories.

rgrep "add_header Pragma public;"  /path/to/directory

The above command will look for the words add_header Pragma public; in all the files located inside the /path/to/directory directory and its subdirectories.

➤ Download a file from a URL using wget
wget https://www.example.com/latest.zip
➤ Add a public key from a URL to the apt sources keyring using curl

First install curl by running apt-get install curl. Then run:

curl http://www.example.com/keys/example_signing.key | apt-key add -
➤ Write multiple commands on a single line

If you want to execute each command only if the previous one succeeded, run:

first_command && second_command && third_command

If you want to execute all commands regardless of whether the previous ones fail or not, run:

first_command; second_command; third_command

You can run as many commands as you want in this manner.





You can send your questions and comments to: