Linux 3
Linux 3
File permissions
Linux follows long Unix history, and has the same kinds of permission and ownership of files and directories. In this
chapter, we will learn in detail about the same.
Let us look at the output of ls -l command.
$ ls -l
total 24
drwxrwxr-x. 2 fedora fedora 4096 Jun 24 08:00 dir1
-rw-rw-r--. 1 fedora fedora 174 Jun 23 13:26 files.tar.bz2
-rw-rw-r--. 1 fedora fedora 164 Jun 23 13:20 files.tar.gz
-rw-rw-r--. 1 fedora fedora 19 Jun 23 14:14 hello.txt
lrwxrwxrwx. 1 fedora fedora 13 Jun 23 12:32 name -> /etc/hostname
The first column contains the permission details of each file and directory. The permissions are displayed using groups
of three values, r for read access, w for write access, and x for execute access. These 3 values are mentioned for owner,
group, and other user accounts. The first - can be d for directories or l for links.
There’s another way to calculate the same file permissions, using numbers.
Read 4
Write 2
Execute 1
This means, if you want to give read and write access only to the owner and group, you mention it like this “660”,
where the first digit is for the owner, second digit is for the group, and the third digit is for the other users. We can use
this format along with the chmod command to change permissions of any file or directory.
chmod is the command which changes the file mode bits. Through chmod command one can alter the access permis-
sions (i.e to permissions to read, write and execute) to file system objects (i.e files and directories). If we look at the
command closely chmod is the abbreviation of change mode. A few examples are given below.
33
Linux command line for you and me Documentation, Release 0.1
In the first line, we created a new file called myfile.txt using the echo command (we redirected the output of echo into
the file). Using the chmod 000 myfile.txt command, we removed the read/write permissions of the file, and as you can
see in the next line, even the owner of the file cannot read it. Setting the mode to 600 brings back read/write capability
to the owner of that particular file.
The executable permission bit is required for directory access, and also for any file you want to execute.
The PATH is a shell variable. When we type a command in the bash shell, it searches for the command in the directories
mentioned in the succeeding/sequential order, in the PATH variable. We can see the current PATH value using the echo
command.
$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/fedora/.local/bin:/home/
˓→fedora/bin
The different directories are separated by :. To a search a particular command the shell will search in the following
sequential order -
• /usr/local/bin
• /usr/bin
• /usr/local/sbin
• /usr/sbin
• /home/fedora/.local/bin
• /home/fedora/bin
You can see the /home/fedora/bin directory is mentioned in the path. This means if we have that directory, and an
executable file is in there, we can use it as a normal command in our shell. We will see an example of this, later in the
book.
~/.bash_profile is the configuration file for bash for the users who are allowed to login (via GUI or via ssh). On Fedora
systems this file also read configuration from the ~/.bashrc file.
One can set environment variables, update $PATH or any other important variables, or commands to execute after
login using this file. But, remember to relogin or source the file (source ~/.bash_profile) after making the change.
The ~/.bashrc is a special configuration file for your bash terminal used for the users who can not login via the standard
methods. These accounts will have nologin marked in the /etc/passwd file. For example:
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
You can define or delete or update environment variables and add commands to execute when a new interactive shell
opens up for the users who can not login.
For example, if want to add a new directory path to the PATH variable, then we can add the following line at the end
of the ~/.bashrc file.
export PATH=/mnt/myproject/bin:$PATH
After modifying the .bashrc file you will have to source it, or open a new tab in your terminal to see the change.
This file is used to configure whenever a new login shell is created. This configures system wide, means if you add
any variable here, that will be available for all users who can login to the system.
We use the which command, to find the exact path of the executable being used by a command in our shell.
$ which chmod
/usr/bin/chmod
$ which tree
/usr/bin/which: no tree in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/
˓→fedora/.local/bin:/home/fedora/bin)
The second example shows the output in case the which command cannot find the executable mentioned.
$ asakj
bash: asakj: command not found...
$ which asakj
/usr/bin/which: no asakj in (/home/adas/.local/bin:/home/adas/bin:/home/adas/.cargo/
˓→bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin)
There is no command as asakj. The shell searched for asakj in the directory as designated under the $PATH varible in
the .bashrc file and not found it - bash: asakj: command not found. . . Then with the which command we can actually
see how does that search work.
she-bang or sha-bang is the first line in scripts; which starts with #! and then the path of the interpreter to be used for
the rest of the file. We will create a simple bash hello world script using the same, and then execute it.
$ vim hello.sh
$ chmod +x hello.sh
$ ./hello.sh
Hello World!
Processes in Linux
A process is a program (think about any Linux application) in a running state. It contains various details, like the
memory space the program needs, a process id, the files opened by the process, etc.
The following command shows all the processes from your computer.
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 215356 4984 ? Ss May29 0:28 /usr/lib/systemd/
˓→systemd --system --deserialize 19
You can see that the output also tells you under which user the process is running, what the actual command being
used is, and the percentage of CPU and memory usage.
The PID column shows the process id; you can see that the systemd process has PID 1, which means it is the first
process to start in the system.
Let’s say, I want to know the process id of the Firefox browser in my system. I can use the following command to find
that information.
37
Linux command line for you and me Documentation, Release 0.1
kdas 26919 0.0 0.0 118520 980 pts/3 S+ 16:17 0:00 grep --color=auto
˓→firefox
Here, we are first running the ps command, and then passing the output of that to the next command using the |
character. In this case, as you see, grep is that second command. We can find and look for text using the grep tool. We
will learn more about grep in the future.
We can kill/stop any process using the kill command. We found out, in the last example, that the id of the Firefox
process in my computer is 26752, we can use that id to kill it.
$ kill 26752
lsof command will show list of all open files. The man page has more details about the different command line options
available.
7.5 Signals
Signals are a limited way to communicate to a process. You can think about them as notifications to a process,
and depending on the signal handler in the code, the process does something with that signal. The kill command
actually sends a signal to the given process id, the default signal is TERM, which says to terminate the process. To
directly/forcibly kill a process, you can send the KILL signal.
$ kill -9 26752
Here 9 is number representation of the KILL signal. To know more about Linux signals, read the man page.
$ man 7 signal
kill command also has a -l flag, which prints all of the signal names, and numbers on the screen.
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
(continues on next page)
top is a very useful command while using a Linux system. It’s a quick way to know about all the running processes in
the system, and their related status about CPU and memory usage in general. To get out of top, press the key q.
top - 17:37:28 up 24 days, 11:52, 2 users, load average: 0.57, 0.73, 0.75
Tasks: 372 total, 2 running, 370 sleeping, 0 stopped, 0 zombie
%Cpu(s): 11.6 us, 2.6 sy, 0.0 ni, 84.9 id, 0.1 wa, 0.3 hi, 0.5 si, 0.0 st
KiB Mem : 7858752 total, 1701052 free, 4444136 used, 1713564 buff/cache
KiB Swap: 3268604 total, 1558396 free, 1710208 used. 2431656 avail Mem
By the way, feel free to press 1 and see if anything changes in the top command output.
If you look at the top output carefully, you will find load average mentioned. Actually, there are 3 numbers provided;
these are the load averages of the system in the last one minute, 5 minutes ago, and 15 minutes ago.
In simple words, load average means the average time any process has to wait to get access to the CPU (or other
resources), in idle state the load average is 0. This information is a quick way to learn about the system, if the system
is slow to respond, just looking at the load-average, and then the rest of the top output should be a good starting point.
htop is a modern version of the top tool. It has many more features, interactiveness being the biggest amongst them.
htop does not come by default in most of the Linux installations, which means you will have to install it using the
system’s package management tool.
These are the ways to install it in Fedora and in Debian/Ubuntu
$ man htop
You can learn more about Linux processes in the glibc manual. Use the info command to find out more.
/proc is a special directory in our filesystem. This is a virtual filesystem which contains information about all the
running processes, and information about the hardware present in the system. You will find that the files in the virtual
filesystem are 0 in size.
Now we’ll learn about a few files inside this directory.
7.11 /proc/cpuinfo
/proc/cpuinfo file has information about the CPU in your system. It includes the model number, and also the various
flags available in that particular CPU model.
7.12 /proc/cmdline
/proc/cmdline file has all the parameters passed to the kernel at the bootup time. The following is a cloud-based virtual
machine.
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-4.8.6-300.fc25.x86_64 root=UUID=9be70055-35f2-4a57-b120-
˓→5a003dfdb504 ro no_timer_check console=tty1 console=ttyS0,115200n8 rhgb quiet
7.13 /proc/meminfo
/proc/meminfo contains information related to the memory in the system. You can see the total amount RAM, the
available memory and other values there.
$ cat /proc/meminfo
MemTotal: 4046820 kB
MemFree: 2960568 kB
MemAvailable: 3696216 kB
Buffers: 53756 kB
Cached: 830052 kB
SwapCached: 0 kB
Active: 347216 kB
Inactive: 575692 kB
Active(anon): 39388 kB
Inactive(anon): 196 kB
Active(file): 307828 kB
Inactive(file): 575496 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 4 kB
Writeback: 0 kB
AnonPages: 39120 kB
Mapped: 42032 kB
Shmem: 488 kB
Slab: 141692 kB
SReclaimable: 114996 kB
SUnreclaim: 26696 kB
KernelStack: 1360 kB
PageTables: 2700 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 2023408 kB
Committed_AS: 127752 kB
(continues on next page)
7.11. /proc/cpuinfo 41
Linux command line for you and me Documentation, Release 0.1
7.14 /proc/uptime
$ cat /proc/uptime
52820.32 104802.84
The first value in this file shows the number of seconds the system is up. The second value is the total number of idle
seconds for each CPU, so for the modern systems, this value can be more than the first value.
This directory is a special one for system administrators. This not only provides information, but also allows you to
quickly change (enable/disable) different kernel features.
We use the sysctl command to view or edit the values for /proc/sys/. If you want to see all the different settings, use
the following command.
$ sudo sysctl -a
[sudo] password for kdas:
abi.vsyscall32 = 1
crypto.fips_enabled = 0
debug.exception-trace = 1
debug.kprobes-optimization = 1
dev.cdrom.autoclose = 1
dev.cdrom.autoeject = 0
dev.cdrom.check_media = 0
dev.cdrom.debug = 0
dev.cdrom.info = CD-ROM information, Id: cdrom.c 3.20 2003/12/17
... long output
$ sysctl net.ipv4.ip_forward
You can see the same value in the /proc/sys/net/ipv4/ip_forward file too.
$ cat /proc/sys/net/ipv4/ip_forward
1
To make the change permanent, write the following in the /etc/sysctl.conf file.
net.ipv4.ip_forward = 1
Linux Services
A service is a process or application which is running in the background, either doing some predefined task or waiting
for some event. If you remember our process chapter, we learned about systemd for the first time there. It is the first
process to run in our system; it then starts all the required processes and services. To know about how the system boots
up, read the bootup man page. Click here to read it online.
$ man bootup
Daemon is the actual term for those long-running background processes. A service actually consists of one or more
daemons.
Make sure that you don’t get confused between Daemons and Demons :) Here is a gem from Internet:
If you look at Unix/Linux history, you will find the first process which starts up, is also known as init process. This
process used to start other processes by using the rc files from /etc/rc.d directory. In the modern Linux systems,
systemd has replaced the init system.
45
Linux command line for you and me Documentation, Release 0.1
Units are a standardized way for the systemd to manage various parts of a system. There are different kinds of units,
.service is for system services, .path for path based ones. There is also .socket which are socket based systemd units.
There are various other types, we can learn about those later.
These are service units, which explains how to manage a particular service in the system. In our daily life, we generally
only have to work with these unit files.
$ systemctl
... long output
-.mount loaded active
˓→mounted /
boot.mount loaded active
˓→mounted /boot
dev-hugepages.mount loaded active
˓→mounted Huge Pages File System
dev-mqueue.mount loaded active
˓→mounted POSIX Message Queue File System
home.mount loaded active
˓→mounted /home
proc-fs-nfsd.mount loaded active
˓→mounted NFSD configuration filesystem
run-user-1000-doc.mount loaded active
˓→mounted /run/user/1000/doc
run-user-1000-gvfs.mount loaded active
˓→mounted /run/user/1000/gvfs
run-user-1000.mount loaded active
˓→mounted /run/user/1000
run-user-42.mount loaded active
˓→mounted /run/user/42
... long output
In the output of the systemctl command, you should be able to see all the different kinds of units in the system. If you
want to see only the service units, then use the following command.
$ systemctl --type=service
Let us take the sshd.service as an example. The service controls the sshd daemon, which allows us to remotely login
to a system using the ssh command.
To know the current status of the service, I execute the following command.
Jun 19 12:07:29 kdas-laptop sshd[19533]: Accepted password for kdas from 192.168.1.
˓→101 port 61361 ssh2
Jun 20 17:58:02 kdas-laptop sshd[30293]: Accepted password for kdas from 192.168.1.
˓→101 port 63351 ssh2
Jun 20 18:32:17 kdas-laptop sshd[32039]: Accepted password for kdas from 192.168.1.
˓→101 port 64355 ssh2
Jun 20 18:45:57 kdas-laptop sshd[32700]: Accepted password for kdas from 192.168.1.
˓→101 port 64824 ssh2
Jun 21 08:44:39 kdas-laptop sshd[15733]: Accepted password for kdas from 192.168.1.
˓→101 port 51574 ssh2
To start the service, I’ll use the following command, and then I can use the status argument to the systemctl to check
the service status once again.
In the same way, we can use either the stop or restart arguments to the systemctl command.
Even if you start a service, you’ll find that after you reboot the computer, the service did not start at the time of boot
up. To do so, you will have to enable the service, or to stop a service from starting at boot, you will have to disable the
service.
We can also reboot or shutdown the system using the systemctl command.
8.10 journalctl
systemd runs the systemd-journald.service, which stores logs in the journal from the different services maintained by
systemd. We use journalctl command to read these log entries from the journal. If you execute the command without
any arguments, it will show you all the log entries starting from the oldest in the journal. One needs to be root to be
able to use the journalctl command. Remember that systemd-journald stores all the logs in binary format, means you
can not just less the files and read them.
If you want any normal user to execute journalctl command, then add them into systemd-journal group.
We can use the journalctl command to find the log of a given service. The general format is journalctl -u service-
name”. Like below is the log for *sshd service.
You can use the -n argument to the journalctl command to view only the last N number of entries. For example, to
view the last 10 entries.
# journalctl -n 10
In case you want to monitor the logs of any service, that is keep reading the logs in real time, you can use -f flag with
the journalctl command.
I can see that someone was trying to break into this VM by trying random ports :)
In systems like Fedora, journalctl by default keeps history from past boots. To know about all available boot history,
type the following command.
To know about any particular boot log, you can use the hash along with -b flag to the journalctl command.
We can also use journalctl to view logs for a certain time period. For example, if we want to see all the logs since
yesterday, we can use the following command.
You can also use date time following YYYY-MM-DD HH:MM:SS format.
Use the –disk-usage flag to find out total amount entries and archive can be stored. The following is the output from
an Ubuntu Focal (20.04) system.
# journalctl --disk-usage
Archived and active journals take up 56.0M in the file system.
In case you are developing a new service, or you want to run some script as a systemd service, you will have to write
a service file for the same.
For this example, we will add a new executable under /usr/sbin called myserver. We will use Python3’s builtin
http.server module to expose the current directory as a simple server.
#!/usr/bin/sh
python3 -m http.server 80
Next, we will create the actual service file, which is configuration file written in INI format.
Add the following to the /etc/systemd/system/myserver.service file.
[Unit]
Description=My Web Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/web/amazing
ExecStart=/usr/sbin/myserver
Restart=always
[Install]
WantedBy=multi-user.target
Using ExecStart we are specifying which executable to use, we can even pass any command line argument to that. We
are also mentioning the directory this service will start. We are also saying in case of a failure, or unclean exit code, or
or on signal always restart the service. The service will also start after the network is up. We are also mentioning that
the service will have /web/amazing as the working directory. So, we should also create that. We also add an index.html
to the same directory for testing.
# mkdir -p /web/amazing
# echo "Hello from Python." > /web/amazing/index.html
To understand the other options you will have to read two man pages,
• man systemd.service
• man systemd.unit.
After adding the service file, reload the daemons.
# systemctl daemon-reload
Unless you do this, systemd will complain to you that something changed, and you did not reloadl. Always remember
to reload after you make any changes to any systemd service files.
Now we can start and enable the service.
Active: active (running) since Sat 2022-03-12 10:03:25 UTC; 1 day 3h ago
Main PID: 21019 (myserver)
Tasks: 2 (limit: 50586)
Memory: 9.6M
CGroup: /system.slice/myserver.service
21019 /usr/bin/sh /usr/sbin/myserver
21020 python3 -m http.server 80
We can verify that our new webservice is running properly via curl.
$ curl http://localhost/
Hello from Python.