Understanding a Linux command

cantguess

New Member
Credits
66
Hello!

We got a new optional task at the University.

Could somebody please explain what does it do exactly?

I know that the first line is a shebang. I used the "man df" to figure out the rest has something to do with disks, but couln't figure out it as a whole.

Honestly, I don't even know how to run it. I'm a true beginner.

Many thanks for the replies in advance!

Code:
#!/bin/bash
a=`df --output=pcent /$1 | grep '[0-9]' | sed 's/%//'`
b=`expr $a \< $2`
echo $b
exit $b
#
 


KGIII

Well-Known Member
Credits
8,066
I'll help you with part of this - by giving you a tool to use.

This is a link ALL Linux users should have in their toolbox.


Note, you can click on elements of the command. So, enter the command, see the results, and then you can click on parts of the command and get information with regards to those commands.

That should get you started.
 

JasKinasis

Well-Known Member
Credits
5,373
Seeing as this has been up for a while now - I'll run through it.

This line:
Bash:
a=`df --output=pcent /$1 | grep '[0-9]' | sed 's/%//'`
The first part runs the df command and displays the percentage of space used on $1.

I know this because the df commands --output option is set to only display the pcent field, which is the "percentage-used" field. So that will be the only field shown in the output.

Also, regarding $1 -
In a shell-script, $1 is the first parameter sent to the script when it is ran. And the position of $1 in the df command is where the df command expects a path to a storage device. Which implies that when this script is ran - the first parameter to the script should be a path to a storage drive attached to the PC - which could be a USB drive, or a HDD, or SDD. So when running/invoking this script - parameter 1 to the script should be a path to a storage device like /dev/sda1.

The output from the df command is then piped through grep and only lines of output containing numbers will be displayed.

The output from grep is then piped through sed - to remove the % symbol and the final output is stored in variable a.

So ultimately - the entire line attempts to find out the percentage of space used (on the device-path passed as parameter 1 to the script). The output is filtered to only contain the percentage (minus the percent sign) and stored in the variable $a.

So if the drive is 75% full - the value of the variable $a would be "75".

The last lines of the script:
Bash:
b=`expr $a \< $2`
echo $b
exit $b
The expr command evaluates whether the value in $a is less than the value in $2 and stores the result in the variable b.

If $a is less than $2, the value of $b will be 1. Otherwise it will be 0.

The value of $b is then displayed on screen and then the script exits with a return status of $b.

NOTE: $2 is the second parameter passed to the script when it is ran.
This implies that the second parameter to the script is a numeric value.

So when running the script you would run it as something like:
./nameofscript.sh /dev/sda1 40

When running the script as above - if the used percentage of the specified drive is less than the number in parameter 2, the script displays and returns 1.
Otherwise - the script displays and returns 0.

So for example if the used percentage was 75% and we used 40 as the second parameter to the script (- as per the above invocation of the script -) then the script would return 0. Because 75 is NOT less than 40.

If the used percentage was 30% and we used 40 as the second parameter to the script - then the script will display and return 1 - because 30 is less than 40.

Also, to finish up:
The script uses a few slightly outdated things that could be modernised a little.
As you're using bash - rather than using the antiquated backticks for command substitution, it's cleaner to use the more modern (and standard) $() syntax.

The backticks aren't a problem per se. You can still use them. But, they are deprecated. The $() syntax has been the preferred method for invoking command substitutions for a while now. It's part of the current POSIX standard.

The problem with back-ticks is that nested back-tick command substitutions require nested backticks to be escaped in a special way. It's very easy to get it wrong and mess things up. The $() syntax is simpler and much cleaner/clearer. Especially when dealing with complex, nested command substitutions.

Likewise, rather than using expr inside backticks, you can use bash's numeric evaluation inside the new command substitutions instead: e.g. $(()).

Also, when using/dereferencing the values from variables - you should double quote the variables to avoid globbing and various other problems.

So a more modern (and standard) way to write the original script in bash would be:
Bash:
#!/bin/bash
a=$(df --output=pcent "$1" | grep '[0-9]' | sed 's/%//')
b=$(( "$a" < "$2" ))
echo "$b"
exit "$b"
#
It's basically the same, but we're using the more modern command-substitution syntax. Using bash's numeric evaluation operators instead of expr. And using double-quotes when dereferencing values from variables.
 
Last edited:

Members online


Latest posts

Top