Exam 2014/09/08

Text:
The comman ls -la provides the following output:

total 56
drwxr-xr-x  4 scanzio scanzio  4096 dic  6 18:39 .
drwxrwxrwt 26 root    root    20480 dic  6 18:39 ..
drwxr-xr-x  2 scanzio scanzio  4096 dic  6 18:38 current
drwxr-xr-x  2 scanzio scanzio  4096 dic  6 18:37 documents
-rw-r--r--  1 scanzio scanzio 11887 dic  6 18:39 .emacs
-rw-r--r--  1 scanzio scanzio  8980 dic  6 18:38 examples.desktop
lrwxrwxrwx  1 scanzio scanzio    10 dic  6 18:39 so -> current/so

Write a bash script that receives in input a list of directory names in the command line, and that for each directory (given the list of its content obtained through the ls -al command) performs the following operations:

Solution:

20140908.sh
#!/bin/bash
 
# Control if the number of parameters is correct (i.e., at least one parameter is needed) 
if [ $# -eq 0 ]
then
   echo "Usage: $0 <list_of_directories>"
   exit 1
fi
 
# Control that all the parameters are effectivelly directories
for i in $*
do
    if [ ! -d $i ]
    then
        echo "$i is not a directly"
        exit 2
    fi
done
 
 
for dir in $* # Cycle on all the directories
do
 
    ls -la $dir > .tmp_$$ # Output of ls -al in the hidden file named .tmp_$$
    while read line #Ciclo su tutte le linee del file
    do
        name=$(echo $line | cut -d " " -f 9)
        if [ "$name" = "." -o "$name" = ".." ]
        then
            continue
        fi
 
        f1=$(echo $line | cut -d " " -f 1) # Extraction of the first column
        # Caso directory
        # Si fa notare che il comando grep se fa il match almeno di un'espressione regolare fa una exit 0 (settando il valore di $?, valori di ritorno dell'ultimo comando, a 0), altrimenti $? e' uguale a 1 
        echo $f1 | grep "^d" > /dev/null
        if [ $? -eq 0 ]
        then
            dname=$(echo $line | cut -d " " -f 9)
            nsubdirs=$(find $dir/$dname -type d | wc -l)
            echo $dir/$dname is a directory having $nsubdirs subdirs
        fi
 
        # Caso file
        echo $f1 | grep "^-" > /dev/null
        if [ $? -eq 0 ]
        then
            name=$(echo $line | cut -d " " -f 9)
            owner=$(echo $line | cut -d " " -f 3)
            size=$(echo $line | cut -d " " -f 5)
            echo $name is a regular file, its owner is $owner and its size is $size bytes
        fi
 
        # Caso link simbolico
        echo $f1 | grep "^l" > /dev/null
        if [ $? -eq 0 ]
        then
            name=$(echo $line | cut -d " " -f 9)
            date=$(echo $line | cut -d " " -f 6,7,8)
            reference=$(echo $line | cut -d " " -f 11)
            echo $name is a link created on $date, it refers to $reference
        fi
    done < .tmp_$$
done
 
rm .tmp_$$
 
exit 0

Output:

$ ./20140908.sh x
x/current is a directory having 1 subdirs
x/documents is a directory having 1 subdirs
.emacs is a regular file, its owner is scanzio and its size is 11887 bytes
examples.desktop is a regular file, its owner is scanzio and its size is 8980 bytes
so is a link created on dic 6 18:39, it refers to current/so