shell script
Linux

How to write practical shell script

In the last post, we’ve talked about regex and we see how to use them in sed and awk for text processing and we discussed before Linux sed command and awk command. During the series, we write small shell scripts but we didn’t mix things up, I think we should take a small step and write a shell script that can be some useful.

The main reason for learning to write a shell script is to be able to create your own Linux utilities. Understanding how to write useful and practical scripts is important.

However, sometimes it helps to do something fun to learn a concept or skill. The scripts in this post they can be lots of fun! And they help empower your script writing concepts.

Our main points are:

Sending messages

Write command

Creating the send script

Monitoring Disk Space

Sending messages

You can send messages to someone by phone or e-mail but one method, not commonly used anymore, is sending a message directly to a fellow system user’s terminal. Because this technique is largely unknown

The shell script helps you to quickly and easily send a message to someone who is logged onto your Linux system.

For this simple shell script, only a few functions are required. Several of the commands are common and have been covered in our series of shell scripting; you can review the posts to understand what we are talking about

The first command needed is the who command. The who command allows you to see all the users currently logged into the system.

$ who

shell scripts who command

To send a message, you only need the first two items. Both the username and the user’s current terminal are necessary

Users can prevent anyone to send them messages via the mesg command. Therefore, before you start attempting to send messages, it’s a good idea to check whether messages are allowed. For yourself, you can simply enter the mesg command like this

$ mesg

shell scripts mesg command

The is n result shows that messaging is turned off. If the result showed is y, messages would be allowed.

To check anyone else’s message status, you can use the who command again. Keep in mind that this checks the message status only for those who are currently logged into the system. You use the -T option to check their message status

If you see dash (-) that means messages are turned off and if you see plus sign (+) that means messages are enabled

To allow messages to be sent to you, if it is turned off, you need to use the message command with the y option like this

$ mesg y

$ mesg

shell scripts allow messages

Sure enough, the command shows is y, which indicates messages are allowed to this user

Of course, we need another user to be able to communicate with him so in my case I’m going to connect to my PC using ssh and I’m already logged in with my user, so we have two users logged onto the system

Now we can send the message from one user to another.

Write command

The primary tool for sending messages between logged in users is the write command. As long as messaging is allowed, the write command allows you to send a message to another logged-in user using his username and current terminal

Note: The write command only allows you to successfully send messages to users logged onto a virtual console terminal. A user logged into the graphical environment (KDE, Gnome, Cinnamon or any) will not be able to receive messages.

We will send a message to testuser user from my user likegeeks like this

$ write testuser pts/1

shell scripts write command

After the message is initiated by the write command, a blank line is shown for you to begin inputting the message text. It may be as many lines as you desire. When the Enter key is pressed, a new line is available for more message text. After you are finished entering message text, the whole message is sent by pressing the Ctrl+D key combination which is end of file signal I recommend you to review the post about signals and jobs.

shell scripts receive message

The receiver can see which user on which terminal sent the message. A timestamp is also included. Notice the EOF shown at the bottom. It indicates End Of File, which lets the message recipient know that this is the entire message.

I think now we have all part to build our shell script

Creating the send script

before we create our shell script, we need to determine whether the user we want to send a message to is logged on the system and this can be done using who command to determine that

logged_on=$(who | grep -i -m 1 $1 | awk '{print $1}')

The results of the who command are piped into the grep command. The grep command uses the -i option to ignore case, so the username to be entered using uppercase or lowercase letters. The -m 1 option is included in the grep command, in case the user is logged into the system multiple times. The grep command produces either nothing, if the user is not logged on, or the username’s first login information. This output is passed to the awk command. The awk command returns only the first item, either nothing or the username. This final output from the awk command is stored in the variable logged_on

Then we need to check the variable logged on if it contains something or not

I recommend you to read the post about if statement and how to use it Bash Script

shell scripts check logged user

The logged_on variable is tested to determine if it is a zero-length variable.

If it is a zero-length variable, the script user is informed via echo commands that the user is not currently logged onto the system, and the script is exited via the exit command. If the user is logged onto the system, the logged_on variable contains the user’s username, and the script continues

Checking if user accepts messages

The next step is to determine whether a logged on user accepts messages

shell script check message allowed

Notice that we use the who command with -T. This displays a (+) next to the username if messaging is allowed. Otherwise, it displays a (-) next to the username, if messaging is not allowed. The results from the who command are then piped into grep and awk to pull out only the messaging indicator. The messaging indicator is stored in the allowed variable. Finally, an if statement is used to test for a messaging indicator not set to +. If the indicator is not set to +, the script user is informed and the script is exited. However, if the messaging indicator shows messaging is allowed, the script continues.

Checking if message was included

To test for the message parameter, an if statement is used like this

shell script check message

Getting the current terminal

Before we send a message, we need to get the user current terminal and stored in a variable

terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')

Then we can send the message

echo $2 | write $logged_on $terminal

Now we can test the whole shell script to see how it goes

$ ./senderscript likegeeks welcome

Let’s see the other shell window

shell script send message

Good!  You can now send simple one-word messages

Sending a long message

Surely you want to send more than just a single word. If you try that with this shell script

$ ./senderscript likegeeks welcome to shell scripting

shell script oneword message

It didn’t work. Only the first word of the message is sent. This is due to the script using parameters and each word is treated as a different parameter. To fix this problem we will use the shift command with the while loop you can review the shift command from our post Bash Scripting

And now one thing need to be fixed the message parameter.

Instead of just sending parameter $2 to the write utility, the script is modified to send the variable, whole_message

echo $whole_message | write $logged_on $terminal

So now the whole script should be like this

If you try now

$ ./senderscript likegeeks welcome to shell scripting

shell script complete message

Awesome!! It worked. Again I’m not here to make a script to send the message to the user but the main reason to review our shell scripting knowledge and use all parts we’ve learned together and see how things work together.

Monitoring Disk Space

We are going to build a shell script utility that will help you determine the top ten disk space consumers for designated directories

The du command displays the disk usage for individual files and directories. The -s option lets you summarize totals at the directory level I recommend you to review my post about du command and all other Main Linux Commands. This comes in handy when calculating the total disk space used by an individual user

$ du -s /var/log/

The listing quickly becomes too detailed. The -S (capital S) option works better for our purposes here, providing a total for each directory and subdirectory individually.

$ du -S /var/log/

shell script du command

Because we are interested in the directories consuming the biggest chunks of disk space, the sort command is used on the listing produced by du

$ du -S /var/log/ | sort -rn

shell script sort command

The -n option allows you to sort numerically. The -r option lists the largest numbers first (reverse order). This is perfect for finding the largest disk consumers

The sed command brings more clarity to this listing. To focus on the top ten disk space consumers, when line 11 is reached, sed is set to delete the rest of the listing. The next step is to add a line number for each line in the listing. To get those line numbers on the same line as the disk space text, combine the text lines using the N command. The sed commands will look like this

you can review my post about sed command

Then we can clean the output using the awk command. The output from the sed command is piped into the awk command and printed using the printf function

awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'

After the line number, a colon (:) is added, and tab (\t) characters are put between the individual fields for each text line’s output row.

shell script format output with sed and awk

Now we understand how the command work let’s write the script

To be productive, the script creates a report for multiple directories. We will make a variable to accomplish this say MY_DIRECTORIES. For our purposes here, the variable is set to just two directories

MY_DIRECTORIES=”/home /var/log”

We will make a for loop to perform the du command on each directory listed in the variable. Each time the for loop iterates through the list of values in the variable MY_DIRECTORIES

So the shell script will look like this

shell script monitor disk usage

Good!! The report shows the disk consumption for both directories in a beautifully formatted report

You can filter files so instead of calculating the consumption of all files you can calculate specific extension *.log or whatever, just change the file globing

One thing I have to mention here in production systems you can’t rely on disk space report instead, consider setting disk quotas. If the quota package is installed

Quota package is specialized for that but here we are learning how sell scripts work when things mix together.

I hope you understand how shell scripts work and how commands work together

Again the shell scripts we’ve introduced here is for showing how shell scripting work, there are a ton of ways to implement any task in Linux

My post is finished for now. I tried to reduce the code length and make everything simple as possible hope you like it

Thank you.