Basics of working in Linux operating system

Initial version: 2024-10-08
Last update: 2024-10-08

In this tutorial you will learn how to connect with Linux operating system to control it via Command Line Interface (CLI). Using CLI you will navigate through the file system and get know how you can create, copy, move, and delete files and directories. Doing this you will learn also about file access permissions, owners, users and groups (of users).

Table of contents


Preface
It's true that modern Linux offers you ability to be controlled via graphical user interface (GUI) as many people normally do in the Windows family OS. Visual interface seems to be attractive and with greater productive power – after all you don't have to type anything (you type less) and many actions you do by clicking, dragging and dropping elements. However, in many cases you have to control Linux without this improvement, using only text commands (for example when you communicate with remote server). In general a command-line interface (CLI) is a means of interacting with a computer program by inputting lines of text called command-lines; particularly you can control this way the whole operating system. CLI is very powerful, offers you great flexibility and often you can complete many tasks much faster than with GUI. You can use Linux with GUI but to be a real Linux user you have to know CLI and its tools.

Connecting with Linux
Telnet command usage
Telnet is an old network protocol that is used to connect to remote systems over a TCP/IP network. It connects to servers and network equipment over port 23. Be aware that telnet is a character-based protocol. Each character you enter on the telnet client will be sent to the server immediately. Therefore, you cannot make typo error in entering your raw command, as delete and backspace will be sent to the server.

Telnet is not a secure protocol and is thus not recommended to be used, however because of its simplicity and openness often temporarily used in secure environments. Instead of using telnet, a more preferred protocol to use is SSH which is encrypted and more secure


The syntax for the telnet command is:


telnet [options] <remote_ip_address> [port]
Running the command without specifying an address opens the telnet interactive mode (to end a session and exit telnet, type quit).

Usage examples

$ telnet 38.76.11.19


SSH
SSH, Secure Shell, is a protocol that allows you to securely connect to a remote computer using a text-based interface. It enables managing other computers, transferring files, and executing commands on a remote machine. On the server's side, an SSH daemon constantly listens to a specific TCP/IP port – the default SSH port number is 22.

You connect to a remote doing the following:


ssh [<username>@]<remote_ip_address>
username is optional and you can add it if remote user name is different than local user name.

Be aware that characters as you are typing entering password are not displayed on the screen.

When using a port number, the following two syntaxes are valid:


ssh [<username>@]<remote_ip_address>:<port>
ssh [<username>@]<remote_ip_address> -p <port>


SSH connection without password


Linux filesystem and traversing through it
Simple characteristics
Early very limited file systems had a single list of files that made up the file system. Through time, as computer system and their operating systems has evolved also file systems were modernized. Modern file systems, in addition to the main list (the root directory) used to hold files, also contain subdirectories that may also contain files or further subdirectories. This gave rise to the concept of parent directories and child directories.

A directory containing a file is the parent (directly) of that file. A directory is the child (direct) of another directory containing it. This gave rise to the concept of a tree-like file system hierarchy, in which each directory may contain subdirectories that may contain further subdirectories. This creates a structure that looks like an "reversed tree" with the root at the top of it:


\
|
+-- [boot]
+-- [etc]
+-- [home]
|   +-- [fulmanp]
|       +-- [classes]
|       |   +-- notes.pdf
|       |
|       +-- [documents]
|           |
|           +-- importantDoc.txt
|
+-- [usr]
+-- [var]
Note that in Linux systems there is slightly different notation of devices like discs or pen-drives. Instead of letters to identify them you have one consistent file system always identified by /. All other devices are represented in this file system as its sub-directories, or being more precisely, as its files because in Linux every device is represented as a file.


In Linux directories are also files, but instead of storing data like regular files, they store the location of other files.


In this model important is that every element (file or directory) is uniquely identified by the path starting at the root of the file system tree and ending at that element. For example the (full or absolute) path to notes.pdf file is: /home/fulmanp/classes/notes.pdf. It is different from the relative path fulmanp/classes/notes.pdf which starts at the current directory which is a directory you stoped traversing filesystem. Relative path is transformed into absolute path by concatenating path to the current directory and relative path. For example, if your current directory is /home/fulmanp/documents and it is "joined" with relative path fulmanp/classes/notes.pdf it results in /home/fulmanp/documents/fulmanp/classes/notes.pdf which of course does not correspond to any element in our case.

Traversing filesystem
Commands
The pwd command allows you to know the current directory name you are in, in other words, it prints (current) working directory.

The ls command allows you to display all the files and directories in the current location (directory), in other words, it lists directory. You may ask, why ls instead of more natural ld command? Probably because ld is in use and corresponds to very important piece of software allowing you to create executable files, so called linker.


ls -l
The cd command allows you to change director in Linux, in other words, moves from one directory to another one.

Special directories:

  • ~ – user's home directory;
  • .. – the directory one level up from the current directory (the parent directory of the current directory);
  • . – the current directory;
  • - – the previous directory.


Directories with space in their names
If the directory or file name you want to type has spaces in its name, you should either surround the path with quotes (') or use the backslash (\) character to escape the space:


'name with space'
name\ with\ space


Examples
  • cd by itself or cd ~ will always put the user in their home directory.
  • cd . will leave the user in the same directory they are currently in (i.e. the current directory won't change).
  • cd ~username will put the user in the username's home directory.
  • cd dir (without a /) will put the user in a subdirectory dir; for example, if you are in /home/fulmanp, typing cd documents will put you in /home/fulmanp/documents.
  • cd .. will move the user up one directory. So, if you are in /home/fulmanp/documents, cd .. moves you to /home/fulmanp, while cd ../.. moves you up two levels, i.e. to /home.
  • cd - will switch the user to the previous directory.


Manipulating files and directories

In Linux files are identified mostly by its contents not by their extension as it is done in Windows. To identify the type of file you can use file command.


Manipulating files
Create

$ touch abc.txt
$ cat > abc.txt [Enter text] [Press Ctrl + D to finish]
$ > abc.txt
$ echo "Hello file" > abc.txt
$ echo 'ab cd
> cd cd ef
> cd ef
> cd ef ef' > abc.txt
Copy and move

cp <source_file> <destination_file> 
If you want to copy more than one file from dirA to dirB, you will use the cp command like this:


cp dirA/file.txt dirA/another_file.txt dirB
As you can see, you will put all the source files first, and the last argument will be the destination.

The shell command intended for moving files is mv. Command:


mv <source> <destination>
moves a source file to the specified destination. For instance:


$ touch example.txt
$ mv example.txt ~/Documents
$ ls ~/Documents
example.txt
You can also rename the file as you move it:


$ touch example.txt
$ mv example.txt ~/Documents/foo.txt
$ ls ~/Documents
foo.txt
It enables you to rename a file even when you don’t want to move it to another location, like so:


$ touch example.txt
$ mv example.txt foo2.txt
$ ls
foo2.txt
Moving a file safely

If you copy a file to a directory where a file of the same name already exists, the mv command replaces without any complains the destination file with the one you are moving. This behavior is called clobbering, and in most cases it is exactly what you intend.

If this behavior is not what you want, you can use the --interactive or -i option to ensure that mv asks for confirmation in the event that two files of the same name are in conflict:


$ mv --interactive example.txt ~/Documents
mv: overwrite '~/Documents/example.txt'?
If you do not want to manually intervene, use --no-clobber or -n instead. This flag silently rejects the move action in the event of conflict:


$ mv --no-clobber example.txt ~/Documents
$ ls
example.txt
Moving many files at once

When moving multiple files, mv treats the final directory name as the destination:


$ mv foo bar baz ~/Documents
$ ls ~/Documents
foo   bar   baz
What do we move?

When a file is created, it is assigned to an inode, which is a fixed point in a file system that’s used for data storage. You can find what inode maps to a file with the ls command:


$ ls --inode example.txt
7344977 example.txt
When you move a file, you don’t actually move the data from one inode to another, you only assign the file object a new name or file path.

File and directory inodes never imply inheritance and are dictated by the filesystem itself. Inode assignment is sequential based on when the file was created and is entirely independent of how you organize your computer.

When moving a file from one hard drive to another, however, the inode is very likely to change. This happens because the new data has to be written onto a new filesystem. For this reason, in Linux the act of moving and renaming files is literally the same action. Whether you move a file to another directory or to the same directory with a new name, both actions are performed by the same underlying program.


Delete
When you use command line to delete files (or directories) you do this permanently and there is no easy way to recover deleted items. Think twice before you delete anything.


To delete the file in the current directory, use the following command:


rm filename
Bypassing multiple filenames as arguments to rm, you can delete multiple files:


rm filename1 filename2 filename3
Manipulating directories
Create
To create new directory use mkdir command


$ mkdir mydir
To create more than one directory simultaneously, specify the names of the new directories after mkdir with a blank space between them:


$ mkdir dir1 dir2 dir3
To create a directory with a directory inside of it, use the -p option:


$ mkdir -p dir4/subdir1
For example, to create a directory called test with default permissions in the /home/fulmanp/nonexisting directory, type the following:


mkdir -p /home/fulmanp/nonexisting/test
The -p results in creating the /home, /home/fulmanp, and /home/fulmanp/nonexisting directories if they do not already exist.

To create a directory called test with rwxr-xr-x permissions type the following:


mkdir -m 755 /home/demo/sub1/Test
Copy and move
By default, the cp command works with files. So if you attempt to copy a directory like this:


cp ./directory1/directory2/ ./test
You will get an error stating:


./directory1/directory2/ is a directory
To copy directories, you have to pass the -r flag:


cp -r ./directory1/directory2/ ./test
This flag informs the cp command to recursively copy a directory and its contents (which could be files or other sub directories).

To move the directory you use the mv command which doesn’t differentiate a file from a directory the way cp does. You use the same syntax:


$ touch foo_file.txt
$ mkdir foo_directory
$ mv foo_file.txt foo_directory
$ mv foo_directory ~/fulmanp/documents


Delete
To remove empty directory, use the rmdir command:


rmdir doc_to_delete
To remove non-empty directories on use the rm with r flag:


rmdir dir_with_some_content

NEVER EVER run the rm -rf / or rm -rf * command because you will delete the whole system or content of the current directory.


Manipulating permisions
Users, groups and ownership
UNIX-type systems allow multiple users to work at the same time. User is a concept that allows for the logical separation of resources and their management (especially permissions). A user can be associated with both a physically existing person (e.g. user fulmanp, which is Piotr Fulmański) and a certain "type of system operations" (e.g. www user with whom the local www server is associated). From the point of view of the operating system, it is not important who or what the user is. What is important is what resources (files, programs, devices, etc.) belong to which of the users and what they can do with them. Each user is identified by the so-called UID (User ID) which is a number, and the so-called username or login such as fulmanp or www are only aliases for UID that make it easier for people to work in the system. Users can be organized using a superior structure, which is a group. Each user can belong to one or more groups. The existence of groups is justified by the desire to control identical permissions assigned to a certain number of users and related to a selected resource. In such a situation, changing the permissions for a group results in changing the permissions for all users included in the group. Every file in a UNIX-type system is (simultaneously) owned by:

  • a certain user,
  • a certain group.


The user who is the owner has the right to modify permissions.

Permissions
Each file in the Linux system has a set of permissions associated with it, which tell you who and what can do with the file. The permissions are:

  • read – the right to read,
  • write – the right to write (modify),
  • execute – the right to execute.


While the meaning of these permissions for files seems fairly obvious, for directories (indicated with d) they require some explanation:

  • r – the ability to browse the contents of the directory,
  • w – the ability to change the contents of the directory,
  • x – the ability to enter into the directory (cd command).


The set of permissions is divided into three groups:

  • permissions for the owner,
  • permissions for the group that owns the file,
  • permissions for all others.


By convention, the presence of a given right is indicated by displaying the appropriate letter, while its absence is signaled by the character . The whole is written as one string. For example, the notation:


rwxr-x--x
means that:

  • active permissions for the owner are: read, write and execute,
  • active permissions for the group are: read and execute,
  • active permission for others is execute.


An example result of using the command ls -l is:


$ ls -l

drwxr-xr-x 3 fulmanp fulmanp 4096   2008-01-02 23:23 materials
-rwxr-xr-x 1 fulmanp fulmanp 163    2007-10-14 00:19 preface.tex
-rw-r--r-- 1 fulmanp fulmanp 51024  2007-10-15 14:01 manual.dvi
-rw-r--r-- 1 fulmanp fulmanp 192775 2008-10-07 14:04 manual.pdf
-rwxr-xr-x 1 fulmanp fulmanp 2471   2008-10-06 09:06 manual.tex
drwxr-xr-x 2 fulmanp fulmanp 4096   2008-10-03 11:56 TEST
-rwxr-xr-x 1 fulmanp fulmanp 53065  2008-10-07 16:58 unix.tex
Notice d letter in front of materials and TEST files indicated they are a directory.

chmod command
To set or modify permissions, use the chmod command. The command syntax is as follows:


chmod [options] permissions file(s)
You define permissions by specifying what you want to do, with what permissions, and for whom. For example, the following entry:


chmod a-x data.txt
means that you delete (the - sign) the x permission from everyone (a means all), i.e. the owner, group, and other people. In general, you have the following symbols at you disposal:

  • u – denoting the owner,
  • g – denoting the group,
  • o – denoting other users,
  • a – denoting all of the above groups (i.e. the owner, group, and other users).


The symbols that decide whether to grant or revoke a right are:

  • + – granting a right,
  • - – taking away a right,
  • = – set exactly that right.


Consider the following examples:


$ ls -l
-rw-r--r-- 1 fulmanp fulmanp   0 2008-10-07 17:19 test.txt
$ chmod a-r test.txt
$ ls -l
--w------- 1 fulmanp fulmanp   0 2008-10-07 17:19 test.txt
$ chmod g+rwx test.txt
$ ls -l
--w-rwx--- 1 fulmanp fulmanp   0 2008-10-07 17:19 test.txt
$ chmod g=w test.txt
$ ls -l
--w--w---- 1 fulmanp fulmanp   0 2008-10-07 17:19 test.txt
If you want you can set multiple permissions to multiple classes:


$ chmod ug+rwx example.txt
This grants read, write, and execute for the user and group.

The method given above is good for changing individual permissions, e.g. removing the right to read for a group. However, if you want to assign a specific set of permissions at once, concerning all three groups, i.e. the owner, the group and other users, then it is much more convenient to use the possibility of specifying permissions using numbers. In such a case, you use the convention that the permission r corresponds to the number 4, the permission w corresponds to 2 and the permission x corresponds to 1. If, for example, you want to set the following rights:


rwxr-x-w-
for the file test.txt, then you specify three numbers as permissions (for each group separately), each of which is the sum of the permissions to be set:


owner group other
     rwx   r-x   -w-
     |||   | |    |
     ||1   4 1    2
     |2
     4
sum: 7     5      2
So the command will take the form:


chmod 752 test.txt


Special file permissions
Special permissions are available for files and directories and provide additional privileges over the standard permission sets that have been described so far.

  1. SUID is the special permission (s or S) for the user access level and always executes as the user who owns the file, no matter who is passing the command. If the file owner doesn't have execute permissions, then uppercase S is used:

    
        $ ls -l /usr/bin/passwd 
        -rwsr-xr-x. 1 root root 21245 Oct 13  2024 /usr/bin/passwd
    
    Note the s where x would usually indicate execute permissions for the user.
  2. SGID indicated by (s or S) for the group access level and allows a file to be executed as the group owner of the file. If set on a directory, any files created in the directory will have their group ownership set to that of the directory owner. This is helpful for directories used collaboratively among different members of a group because all members can access and execute new files.

    This permission set is noted by a lowercase s where the x would normally indicate execute privileges for the group.
  3. The sticky bit is a directory-level special permission that restricts file deletion, meaning only the file owner can remove a file within the directory.

    This permission does not affect individual files. However, at the directory level, it restricts file deletion. Only the owner (and root) of a file can remove the file within that directory.

    The permission set is noted by the lowercase t, where the x would normally indicate the execute privilege.


  4. Setting special permissions

    To set special permissions on a file or directory, you can utilize either of the two methods outlined for standard permissions above: symbolic or numerical.

    Assume that you want to set SGID on the directory test.

    To do this using the symbolic method, you do the following:

    
    $ chmod g+s test
    
    Using the numerical method, you need to pass a fourth, preceding digit in the chmod command. The digit used is calculated similarly to the standard permission digits:

    
    SUID = 4
    SGID = 2
    Sticky = 1
    
    The syntax is:

    
    $ chmod X### file_or_directory
    
    where X is the special permissions digit.

    Here is the command to set SGID on test using the numerical method:

    
    $ chmod 2770 test/
    $ ls -ld test/
    drwxrws---. 2 fulmanp fulmanp 113 Oct  9 12:10 test/
    


    Other characters on permissions list
    Sometimes you can find other than listed so far characters on permissions list:

    • + suffix indicates an access control list that can control additional permissions.
    • . suffix indicates an SELinux context is present. Details may be listed with the command ls -Z.
    • @ suffix indicates extended file attributes are present.
    • l prefix mean that it is a symbolic link.


    
    $ ls -l /tmp
    lrwxr-xr-x@ 1 root  wheel  11 17 lip 12:49 /tmp -> private/tmp
    
    A symbolic link is a special type of file that contains a reference to another file or directory in the form of an absolute or relative path and that affects pathname resolution.

    Symbolic links are different from hard links. Hard links do not link paths on different volumes or file systems, whereas symbolic links may point to any file or directory irrespective of the volumes on which the link and target reside. Hard links always refer to an existing file, whereas symbolic links may contain an arbitrary path that does not point to anything.


    The following command creates a symbolic link:

    
    ln -s <target_path> <link_path>
    
    Consider the following example:
    
    $ mkdir -p /tmp/one/two
    $ echo "test_a" >/tmp/one/two/a
    $ echo "test_b" >/tmp/one/two/b
    $ cd /tmp/one/two
    $ ls -l
    -rw-r--r-- 1 user group 7 Jan 01 10:01 a
    -rw-r--r-- 1 user group 7 Jan 01 10:01 b
    
    $ cd /tmp
    $ ln -s /tmp/one/two three
    $ ls -l three
    lrwxrwxrwx 1 user group 12 Jul 22 10:02 /tmp/three -> /tmp/one/two
    $ ls -l three/
    -rw-r--r-- 1 user group 7 Jan 01 10:01 a
    -rw-r--r-- 1 user group 7 Jan 01 10:01 b
    
    $ cd three
    $ ls -l
    -rw-r--r-- 1 user group 7 Jan 01 10:01 a
    -rw-r--r-- 1 user group 7 Jan 01 10:01 b
    $ cat a
    test_a
    $ cat /tmp/one/two/a
    test_a
    $ echo "test_c" >/tmp/one/two/a
    $ cat /tmp/one/two/a
    test_c
    $ cat a
    test_c
    


    Manipulating owners, users and groups

    Only the root user or a user with sudo can create new groups.


    Creating users
    
    sudo useradd foo_user
    
    To view the groups the current user account is assigned to, run the groups command. You'll see a list of groups:

    
    $ groups
    


    Creating groups and adding users
    
    $ sudo groupadd new_group
    $ sudo usermod -a -G new_group foo_user
    $ grep new_group /etc/group
    
    Add a user to multiple groups:

    
    usermod -a -G group1,group2,group3 user_name
    


    The group ID

    If you want to create a group with a specific group ID (GID), use the --gid or -g option:

    
    $ sudo groupadd -g 1009 demo1
    
    You can change the group ID of any group with the groupmod command and the --gid or -g option:

    
    $ sudo groupmod -g 1011 demo1
    


    Rename a group
    You can rename a group using groupmod with the --new-name or -n option:

    
    $ sudo groupmod -n test demo1
    


    Change a user's primary group
    While a user account can be part of multiple groups, one of the groups is always the primary group and the others are secondary groups. The user's login process as well as files and folders the user creates will be assigned to the primary group.

    To change the primary group a user is assigned to, run the usermod command:

    
    usermod -g primarygroup exampleusername
    
    To remove a specific user from a group, you can use the gpasswd command to modify group information:

    
    $ sudo gpasswd --delete user1 demo
    


    Delete a group
    When a group is no longer needed, you delete it by using the groupdel command:

    
    $ sudo groupdel demo
    


    Changing user ownership of a single file
    You use the chown command to change ownership. Its syntax is:

    
    chown [options] new_owner[:new_group] file(s)
    
    To change ownership from a specific user (e.g., fulmanp) to another (e.g., root), where the current owner must be master, use the following syntax:

    
    chown --from=fulmanp root foo_dir
    
    This command ensures that ownership is changed from fulmanp to root only when the current owner is fulmanp.

    To duplicate the ownership of one file (e.g., foo_file) onto another file (e.g., bar_file), use the following syntax:

    
    chown --reference=foo_file bar_file
    
    This command copies the ownership details from foo_file to bar_file, ensuring consistency in ownership between the two files.

    Changing group ownership of a single file
    To change the group ownership of a file you use chgrp command:

    
    chgrp new_group test.txt
    
    As in case of the owner, you use the reference file to change the group of another file or folder:

    
    chgrp -R --reference=ref_file.txt test.txt
    
    To change the group ownership of a file you can also use the chown command:

    
    chown :new_group file1.txt
    


    Sending data to/from remote system
    If you want to send data from your local directory project to remote system at address 192.168.1.3 as user pi you may use scp command in the following way:

    
    scp -r project/ pi@192.168.1.3:
    
    To get data from remote system at address 192.168.48.3 and directory data of user fulmanp and save them in the current location (.) you may use scp command in the following way:

    
    scp -r fulmanp@192.168.48.3:data/ .
    


    Archives
    To create archive you may use the tar command. Its basic structure is as follows:

    
    tar <options> <archive-file> <file or directory to be archived>
    
    For example:

    
    tar -cvzf archive_name.tgz file_or_dir_1 file_or_dir_2
    
    To extract the archive you previously created you may use the following syntax:

    
    tar -zxvf archive_name.tgz