Shell script code not really understandable for me

I have a script:

 DAYS=10
 print_usage() {
        echo "\n"
        echo "Usage: $PROG [-days] [-file|-dir] dir1 [ dir2 ... dirN]"
        echo "       This program will delete all file/directories that are beyond "
        echo "       'x days' old."
        echo "           -days      - This flag allows you to define x days [default:10]"
        echo "           -file|-dir - This flag allows one to remove files [default: directories]"
        echo "\n"
}
  
  
         while [ ! -z "$1" ]
        do
                case $1 in
                        -file* | -f*)
                                TYPE="f"
                                ;;
                        -link* | -l*)
                                TYPE="l"
                                ;;
                        -dir* | -d*)
                                TYPE="d"
                                ;;
                        -1* | -2* | -3* | -4* | -5* | -6* | -7* | -8* | -9* | -0* )
                                DAYS=`echo $1 | awk -F- '{printf("%d",$2)}'`
                                ;;
                        -* )
                                print_usage
                                exit -3
                                ;;
                        * )
                                if [ -d $1 ]
                                then
                                        if [ "$TYPE" = "f" or "$TYPE" = "l" ]
                                        then
                                                echo "Searching $1 for files that are $DAYS days old"
                                                find $1 -type $TYPE -mtime +$DAYS -print -exec /usr/bin/rm -f {} \;
                                        else
                                                echo "Searching $1 for directories that are $DAYS days old"
                                                TMP_LOG=$LOG_HOME/delete.$$
                                                find $1/* -type $TYPE -mtime +$DAYS -print > ${TMP_LOG}
                                                cat $TMP_LOG
exit;
                                                for rm_file in `cat $TMP_LOG | grep -v 'log$'`
                                                do
                                                        if [ -d ${rm_file} ]
                                                        then
                                                                /usr/bin/rm -rf ${rm_file}
                                                        else
                                                                echo "Skipping ${rm_file} because, either root dir is removed or it is not a directories"
                                                        fi
                                                done
                                                /usr/bin/rm -f $TMP_LOG
                                        fi
                                 else
                                        echo "Following is NOT a DIRECTORY: $1"
                                fi
                 esac


 

We call this script from another like this:

 /export/applications/dte/sh/clean_disk.sh -60        /export/applications/dte/web/release 
  
 /export/applications/dte/sh/clean_disk.sh -14 -file  ${DTE_WDATA_DIR}/log
  
  /export/applications/dte/sh/clean_disk.sh -30 -link  /export/applications/dte/web/data/outfiles
 

I don't understand, why case we check $1 and try to set up type as file, link, dir, if $1 is always DAYS
And why script is checking $1 as directory, when we definitely know that it is a number?

Thanks for contribution

I think it is a generally accepted convention that square brackets ("") means the argument is optional.
So, in your script, only "dir1" is mandatory - the rest of the arguments are optional.
In other words, $1 will be a number if it is specified.

You could, alternatively, execute your script as such:

 /export/applications/dte/sh/clean_disk.sh /export/applications/dte/web/release 
 

For such an invocation, dir1 is "/export/applications/dte/web/release"
and DAYS takes the default value of 10.
Which is the same as:

 /export/applications/dte/sh/clean_disk.sh -10 /export/applications/dte/web/release 
 

(At least that is what the "print_usage" function tries to convey. I haven't really reviewed or tested your script to see if it actually does what it says it does.)

I think you left out an important part of the script. There must be a "shift" somewhere below that "esac", which will change the value of $1.

When $1="A", $2="B", $3="C", shift tosses the value of $1 then sets $1="B", $2="C".

If you give shift a value, like shift 2, it deletes n leading arguments, not just one.

In this manner you can loop through all arguments while just checking $1.

I don't like the way they do the loop, though. Just because an argument is blank doesn't mean its the last argument, what if it's supposed to be blank for some reason?

1 Like

Sorry, you are right. There is a shift and I already understand, what is going on

Thanks for contribution