1. Introduction

In this article, we’ll review some of the questions about Linux and Shell Scripting that are often asked in technical interviews. Equally important, we’ll learn the concepts through examples so that we can understand them in a more clear and crisp manner.

2. Questions

Q1. How to Execute a Shell Script?

First, we need to give execute permissions to our script myscript.sh using the chmod command:

chmod +x myscript.sh

Then we can run the script by providing its absolute or relative path starting from the current working directory.

./myscript.sh

Here, the dot (.) refers to the current directory.

Q2. What Is the Difference Between the .bashrc and .bash_profile Files?

Both .bashrc and .bash_profile are startup files containing shell commands. Moreover, they are hidden files located in the user’s home directory.

Bash reads and executes .bash_profile when it’s invoked as an interactive login shell, whereas .bashrc is executed when Bash is invoked as an interactive non-login shell.

When we create a new Bash instance by executing the bash command on the terminal, it’s an interactive non-login shell. 

We should include all the custom prompt settings, aliases, and history command customizations in the .bashrc file. Generally, as a rule of thumb, we then source the .bashrc from .bash_profile:

if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

This ensures that whenever we take a fresh ssh login on the terminal (interactive), both .bashrc and .bash_profile are executed.

Q3. What Is the Use of the source Command in Bash?

The source command executes the commands contained in the script or file that is passed as an argument, and it executes them in the current shell:

source myscript.sh

Note that it’s different from the traditional way of executing a script. When we execute a shell script as ./myscript.sh, for example, a new shell is launched to run the script.

The source command also has the dot (.) command as a synonym:

. .bashrc

This command loads the functions, variables, and other configurations set in the .bashrc file into the current shell environment.

Q4. What Does export Do in Bash?

The export command makes a variable available to all the sub-processes of the current shell:

$ var1="Lets Learn Linux"
$ echo $var1
Lets Learn Linux
$ var2="Interview Prep!"
$ export var2
$ bash
$ echo $var1

$ echo $var2
Interview Prep!

In this example, since var2 was exported, it was available within the subshell of the current shell. Note that we created a new Bash shell by using the bash command. Consequently, variable var1 isn’t visible in the new shell, and we observed a blank output.

Q5. What Are the Linux File Permissions?

File permissions in Linux can be broadly categorized into:

  1. read (r) – The ability of a Linux user to read a file or list a directory.
  2. write (w) – The ability of a Linux user to write to a file or to add new files within a directory.
  3. execute (x) – The ability of a Linux user to run (execute) a file or to list files within a directory (execute commands on a directory).

We can further categorize ownership of files in Linux into:

  1. User (u) – It’s generally the user who has created the file and has full permissions on the file.
  2. Group (g) – We can create groups in Linux and then add the users to a particular group. Further, we can allow all users in a particular group to read, modify, and execute the file.
  3. Others (o) – It means all the other users on the system except the user that has created the file, or the group the user belongs to. Practically, it means everybody else.

We can use ls to list the file to check its permissions. The first column includes 9 characters that indicate read, write, and execute permissions for user, group, and others, respectively:

$ ls -lrt out.txt
-rw-r--r-- 1 shubh baeldung 33 Sep 10 21:33 out.txt

Here, the owner of file out.txt has read and write permissions (rw), and the group and others have only the read (r) permission.

Q6. How Do You Change File Permissions?

We can use the plus (+) or minus (-) operator to add or revoke the file permissions using the chmod command. Along with the operator, we must specify the letters corresponding to the permissions: r (read), w (write), and x (execute). Let’s verify this by adding execute permissions to a file:

$ touch file.txt && ls -lrt file.txt
-rw-r--r-- 1 shubh baeldung 0 Jan 14 13:49 file.txt
$ chmod +x file.txt && ls -lrt file.txt
-rwxr-xr-x 1 shubh baeldung 0 Jan 14 13:49 file.txt

This provides execute permissions to all: user, group, and others. However, we can restrict this by adding one or more of the optional letters: u (user), g (group), o (others), or a (all). Let’s add write and execute permissions to the group:

$ chmod g+wx out.txt
$ ls -lrt out.txt
-rw-rwxr-- 1 shubh baeldung 33 Sep 10 21:33 out.txt

In Linux, the binary reference for the read permission is 4. And it’s 2 and 1 for write and execute permissions, respectively. Hence, all combinations of file permissions can also be represented by a three-digit octal number:

Number

Permission Type

Symbol

0

No Permission

– – –

1

Execute

– -x

2

Write

-w-

3

Execute + Write

-wx

4

Read

r- –

5

Read + Execute

r-x

6

Read +Write

rw-

7

Read + Write +Execute

rwx

Hence, we can also modify permissions as:

$ ls -lrt out.txt
-rw-rwxr-- 1 shubh baeldung 33 Sep 10 21:33 out.txt
$ chmod 715 out.txt && ls -lrt out.txt
-rwx--xr-x 1 shubh baeldung 33 Sep 10 21:33 out.txt

Q7. What Is a Sticky Bit?

The sticky bit is advanced file permission and is generally utilized to protect the files within a public directory. If we set the sticky bit on a directory, a file under this directory can be deleted only by either the owner of the file/directory or the root user.

A typical real-world sticky bit example is the /tmp directory:

$ ls -ld /tmp
drwxrwxrwt 24 root root 980 Feb  3 21:41 /tmp/

This lower-case ‘t’ indicates that the /tmp directory has the sticky bit set. With the sticky bit, any user can still create files under /tmp. However, a user can only delete files owned by himself.

Q8. What Are the Default Permissions of a File When It’s Created?

The default file and directory permissions are governed by the umask value. We can verify the value using the umask command:

$ umask
0022

The default permission of the new file can be derived by subtracting the umask value from the permission value 666. However, in the case of directories, we need to subtract the umask value from 777. For example, if the default umask is 002, new files will be created with the 664 permissions and new directories with the 775 permissions.

Q9. What Is Swap Space?

The swap space is located on a disk, in the form of a partition or a file. Linux uses it to extend the memory available to processes, storing infrequently used pages there. We usually configure swap space during the operating system installation. However, it can also be set later by using the mkswap and swapon commands.

We can check the used and free swap space and memory using the free command:

$ free
              total        used        free      shared  buff/cache   available
Mem:        8269412     5652220     2387840       17720      229352     2483460
Swap:      15483260      379928    15103332

Q10. How to Check Inode Space Utilization in Linux?

We can check the inode space utilization using the df command:

$ df -i

Moreover, if we want to specifically check for a particular disk partition, we can specify an additional argument:

$ df -i /dev 
Filesystem Inodes IUsed IFree IUse% Mounted on 
none 504299 26 504273 1% /dev 

We must note that Linux inode space is different from disk space.

A symbolic or soft link is a file that just stores the path of the original file and not its contents. Consequently, if we move or delete the original file, then the soft link also breaks. It’s analogous to creating shortcuts in Windows OS.

We can create a soft link using the ln command:

$ ln -s out.txt out_link
$ ls -lrt out*
-rwx--xr-t 1 shubh shubh 33 Sep 10 21:33 out.txt
lrwxrwxrwx 1 shubh shubh  7 Dec 25 12:02 out_link -> out.txt

We can use the link to access the file:

$ cat out_link
Output will be logged in out.txt

And, if we rename the file, or move it to a different location, or delete it, the link breaks:

$ mv out.txt out.log
$ ls -lrt out*
-rwx--xr-t 1 shubh shubh 33 Sep 10 21:33 out.log
lrwxrwxrwx 1 shubh shubh  7 Dec 25 12:02 out_link -> out.txt
$ cat out_link
cat: out_link: No such file or directory

A hard link is a different file that points to the same underlying inode as the original file. And so, it references the same physical file location. Like soft links, we can also create hard links using the ln command:

$ ln out.log link_to_log
$ ls -lrti *log*
54324670505239531 -rwx--xr-t 2 shubh shubh 33 Sep 10 21:33 out.log
54324670505239531 -rwx--xr-t 2 shubh shubh 33 Sep 10 21:33 link_to_log
$

As we can verify, both the files have the same inode number (54324670505239531). We can also access the file using a hard link:

$ cat link_to_log
Output will be logged in out.txt

Moreover, even if we remove, rename, or delete the original file, we can still access its contents using the hard link:

$ mv out.log out.txt
$ cat link_to_log
Output will be logged in out.txt

Q13. How to List the Full Path of a File Along With Its Name?

We can use the special variable PWD along with the ls command to get the full path:

$ ls -lrt  "$PWD"/out*
-rwx--xr-t 2 shubh shubh 33 Sep 10 21:33 /home/shubh/out.txt
lrwxrwxrwx 1 shubh shubh  7 Dec 25 12:02 /home/shubh/out_link -> out.txt

An alternative approach is to use the readlink command:

$ readlink -f out.txt
/home/shubh/out.txt

Q14. How Can We Create Logging Within Shell Scripts?

We can use the exec command to redirect stdout (FD 1) to a log file:

#! /bin/bash
script_log="/tmp/log_`date +%F`.log"
exec 1>>$script_log
echo "This will be written into log file rather than terminal.."
echo "This too.."

Now let’s check how we can also write the standard error to the same file:

#! /bin/bash
script_log="/home/shubh/log_`date +%F`.log"
exec 1>>$script_log
exec 2>&1
datee
echo "Error for the typo in date command will be logged in the log file"
date
echo "Output of correct date command will also be logged in log file, including this echo statement"

Here we copied the stderr (2) to stdout (1), and stdout was already changed to write into the log file.

Q15. How Can We Suppress stdout and stderr in Bash?

We can suppress the output or the errors thrown by a Linux command or script by redirecting the stdout and stderr to the null device:

$ date
Fri Dec 25 13:20:19 IST 2020
$ date > /dev/null
$

Here, we suppressed the stdout by redirecting it to /dev/null.  To redirect both stdout and stderr, we must redirect stderr to stdout and then redirect stdout to /dev/null:

$ cat out.log
cat: out.log: No such file or directory
$ cat out.log > /dev/null 2>&1
$

2>&1 is a shorthand to redirect stderr to stdout.

Q16. How to Display a Line From a File Containing the Keyword ‘ERROR’ and Its Surrounding Lines?

We can use the grep command to match a pattern within a file and display it:

$ grep ERROR subtitles.txt
Dialogue: 0,1:11:43.23,1:xx [ERROR: failed to parse ],Default,,0,0,0,,the dawn is coming.

Next, to get the surrounding line on each side of the matching pattern, we can use the C option of the grep command:

$ grep -C1 ERROR subtitles.txt
Dialogue: 0,1:11:40.35,1:11:42.43,Default,,0,0,0,,And I promise you...
Dialogue: 0,1:11:43.23,1:xx [ERROR: failed to parse ],Default,,0,0,0,,the dawn is coming.
Dialogue: 0,1:11:44.82,1:11:49.37,Default,,0,0,0,,One day, the Batman will have to answer for the laws he's broken.

The CN option of the grep command also prints the N lines before and after the line matching the pattern.

Q17. How to Check the List of Running Processes?

We can list the processes using the top command. It provides an interactive and real-time interface:

$ top
top - 13:56:25 up 5 days, 23:37,  0 users,  load average: 0.52, 0.58, 0.59
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.0 us,  1.1 sy,  0.0 ni, 97.5 id,  0.0 wa,  0.4 hi,  0.0 si,  0.0 st
KiB Mem :  8269412 total,  2187168 free,  5852892 used,   229352 buff/cache
KiB Swap: 15483260 total, 15078760 free,   404500 used.  2282788 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0    8936    192    148 S   0.0  0.0   0:00.23 init
   76 root      20   0    8936    224    180 S   0.0  0.0   0:00.00 init
   77 shubh     20   0   16916   3612   3500 S   0.0  0.0   0:01.21 bash
  354 shubh     20   0   17624   2008   1436 R   0.0  0.0   0:00.01 top

As we can verify, the top command also lists the summary of various system resources in the first few lines. Similarly, another alternative to list processes is to use the ps command:

$ ps -aef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Dec19 ?        00:00:00 /init
root        76     1  0 Dec23 tty2     00:00:00 /init
shubh       77    76  0 Dec23 tty2     00:00:01 /bin/bash --login
shubh      355    77  0 14:03 tty2     00:00:00 ps -aef

Q18. What Is a Zombie Process?

When a process completes its job, its parent is notified by the SIGCHLD signal. The parent then executes the wait() system call to read the status of the child process and reads its exit code. This also cleans up the entry of the child process from the process table and hence, the process finishes.

However, if a parent process isn’t programmed to execute the wait() system call on the creation of the child process, proper cleanup doesn’t happen. Consequently, the parent process cannot monitor the state changes of the child processes. This causes the zombie state of the finished process to stay in the process table, and hence it appears in the process list as a zombie process.

Zombie processes in Linux are sometimes also referred to as defunct or dead processes. Zombie processes are cleaned up when their parent process is killed or finishes execution.

Q19. Write a Command That Will Look for Files That Have the Extension “.java” and an Occurrence of the String “extends” in It.

We can use the find command to find all .java files containing the word “extends” in the “app” directory:

find app -name "*.java" -type f -exec grep -l extends {} \;

Here, we specified the option -type f  to find only the regular files. Thereafter, we used the -exec option to execute the grep command on the list of files returned by the find command. Note the semi-colon at the end causes the grep command to be executed for each file, one at a time, as the {} is replaced by the current file name. Note also a backslash is required to escape the semi-colon from being interpreted by the shell.

Q20. How Can We Calculate the Space Occupied by a Directory?

We can get the space occupied by a directory using the du command:

$ du -sh Codes
9.4M    Codes

Further, to track down disk space within a directory, we can list the files ordered by space, using the S option of the ls command:

$ ls -lrSh | tail -2
-rwxrwxrwx 1 shubh shubh 225K Jul 17  2018 pagerank.zip
-rwxrwxrwx 1 shubh shubh 6.4M Dec 13  2016 mbox.txt

As shown above, this command lists the two largest files within a directory.

Q21. How Can We Find a Pattern in a File Without Using the grep Command?

Let’s first check the solution using the sed command:

$ sed -n '/ERROR/ p' subtitles.txt
Dialogue: 0,1:11:43.23,1:xx [ERROR: failed to parse ],Default,,0,0,0,,the dawn is coming.

Here, we specified the pattern ERROR along with the print (p) function. We also specified the -n flag to suppress sed from printing the buffer. We can also use the awk command to print the line containing the pattern:

$ awk '/ERROR/' subtitles.txt
Dialogue: 0,1:11:43.23,1:xx [ERROR: failed to parse ],Default,,0,0,0,,the dawn is coming.

Q22. How Can We Search and Replace a Pattern Within a File?

Let’s replace the pattern ‘ERROR’ with ‘WARN’ in the subtitles.txt file using the sed command:

$ sed -i 's/ERROR/WARN/g' subtitles.txt
$ grep "WARN" subtitles.txt
Dialogue: 0,1:11:43.23,1:xx [WARN: failed to parse ],Default,,0,0,0,,the dawn is coming.

Here we used the g (global) flag to replace all occurrences of pattern in the file. Additionally, the -i option tells sed to edit the input file in-place.

Q23. How to Print Only the Nth Line of a File?

Let’s use the sed command to print the 8th line of the profile file:

$ sed -n '8p' /etc/profile
    if [ -f /etc/bash.bashrc ]; then

Here we used the print function and the -n flag of the sed command. Alternatively, we can also use the awk command:

$ awk '8 == NR' /etc/profile
    if [ -f /etc/bash.bashrc ]; then

In this snippet, we used the awk built-in variable NR, which holds the total number of records read so far by the awk command.

Q24. What Is Shebang in a Shell Script?

The shebang (“#!”) tells the system how to interpret a script. In fact, all scripts in Linux execute using the interpreter specified on the first line of the script file:

#!/bin/bash

Almost all bash scripts start with this line (assuming that the bash executable is located in the /bin path). Moreover, this ensures that the Bash shell always acts as an interpreter, even if we’re executing the script under another shell.

Q25. How to Debug a Bash Script?

One of the most effective ways to debug a shell script is to add the verbose (-v) and xtrace (-x) mode switches in the command-line while executing the script:

bash -xv ./myscript.sh

The verbose mode allows us to view each command before evaluation. In contrast, the xtrace mode prints the trace of commands for each line after expansion but before execution. Hence, we can combine both -x and -v options to see how statements look like before and after variable substitutions. Another equivalent is to enable the modes within a script using the set command.

Q26. How Can We Add All the Values in the Nth Column of a CSV File?

Let’s consider a sample CSV file:

$ cat addme.csv
1,10,6
2,20,5
3,70,5

We’ll now add the values in the second column of this file using the awk tool:

$ awk -F "," '{Total=Total+$2} END{print "Total is: " Total}' addme.csv
Total is: 100

In this example, we fetched the columns delimited by a comma for every record in the input file addme.csv. Further, we kept on adding the values in the second column to the Total variable. Then, after processing all the records, we printed the total using the END block.

3. Conclusion

In this article, we covered some of the questions that you may face during a technical interview. This is by no means an exhaustive list and should only be considered as the start of further research.

We, at Baeldung, wish you success in any upcoming interviews. We hope these questions will help you land your dream job.