Labs: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.
Learning outcomes are covered in the previous lab.
Graded tasks (deadline: Apr 3)
These tasks are shared by 05 and 06.
06/dir.sh
(30 points)
Create a script for listing file sizes.
The script would partially mimic behaviour of ls
: without arguments it
lists information about files in the current directory, when some arguments
are provided, they are treated as list of files to print details about.
Example run can look like this:
./06/dir.sh /dev/random 06/dir.sh 06
/dev/random <special>
06/dir.sh 312
06 <dir>
The second column will display file size for normal files, <dir>
for directories and <special>
for any other file.
File size can be read through the stat(1)
utility.
Nonexistent files should be announced as FILENAME: no such file or directory.
to stderr.
You can safely assume that you will have access to all files provided on the command-line.
You will probably find the column
utility useful, especially the following
invocation:
column --table --table-noheadings --table-columns FILENAME,SIZE --table-right SIZE
You can assume that there filenames will be reasonable (e.g. without spaces). To simplify things, we will not check exit code to be different when some of the files were not found.
06/scoring.sh
(50 points)
Write a shell script that sums points in a tournament.
The scripts reads a simple text format from stdin, where each line consists of two fields (separated by whitespace): team id and number of points.
After reading the data, the script prints sum of points for each team in passwd-style format (fields separated by a colon).
Example run can look like this:
alpha 5
charlie 8
bravo 10
alpha 7
bravo 2
bravo 3
Output:
alpha:12
bravo:15
charlie:8
We expect you would use temporary files to store the points for each team.
Use mktemp
and clean-up your files afterwards properly.
You can safely assume that the team ids are sane and can be used to create a filename (i.e., no spaces, slashes, colons etc.).
06/sysinfo.sh
(50 points)
Write a shell script that is able to print the following information:
- current system load (see
/proc/loadavg
) - current system (kernel) version (
uname -r
) - number of processors (
nproc
)
Note that the tests expects that you will use the above commands/files inside your script. Other commands are not mocked and the tests will not work.
When the program is executed without any arguments, it prints the information in the following format.
load=0.05 kernel=5.15.fc34.x86_64 cpus=12
If the program is launched with any of the following options, only the relevant part of the output is displayed:
-l
or--load
for current system load-k
or--kernel
for kernel version-c
or--cpus
for number of processors
Running the program with -h
or --help
should print a short help
(see tests for the exact format).
Adding -s
or --script
will print the individual values each on a separate
line.
Examples
$ 05/sysinfo.sh
load=0.05 kernel=5.15.fc34.x86_64 cpus=12
$ 05/sysinfo.sh -k --load
load=0.06 kernel=5.15.fc34.x86_64
$ 05/sysinfo.sh --script
load=0.12
kernel=5.15.fc34.x86_64
cpus=12
$ 05/sysinfo.sh -s -c
cpus=12
06/plot.sh
(70 points)
Write a shell script for drawing a labeled barplot. The user would provide data in the following format:
12 First label
120 Second label
1 Third label
The script will print graph like this:
First label (12) | #
Second label (120) | #######
Third label (1) |
The script will accept input filename as the first argument and will adjust the width of the output to the current screen width. It will also align the labels as can be seen in the plot above.
You can safely assume that the input file will always exist and that it will be possible to read it multiple times. No other arguments need to be recognized.
Hints
Screen width is stored in the variable $COLUMNS
. Default to 80 if the variable
is not set. (You can assume it will be either empty (not set) or contain a
valid number).
The plot should be scaled to fill the whole width of the screen (i.e. scaled up or down).
You can squeze all consecutive spaces to one (even for labels), the first and second column are separated by space(s).
See what wc -L
does.
Note that the first tests use labels of the same length to simplify writing the first versions of the script.
Consider using printf
for printing the aligned lables.
The following ensures that bc
computes with fractional numbers but the result is
displayed as an integer (which is useful for further shell computations).
echo 'scale=0; (5 * 2.45) / 1' | bc -l
Examples
2 Alpha
4 Bravo
# COLUMNS=20
Alpha (2) | ####
Bravo (4) | ########
2 Alpha
4 Bravo
16 Delta
# COLUMNS=37
Alpha (2) | ###
Bravo (4) | ######
Delta (16) | ########################