Shell script & good way to prevent accidental Unix " rm -r * " : Linux & HP-UX


Can anyone provide a Shell script such that if

a) if the person issues "rm -r *", the script will check if the current directory
    is / or /var or /usr or /oracle (or any additional directories that I may add
    from time to time),  it will not echo out a message, you are about to execute
    a dangerous delete from `pwd` & then come back to command prompt

b) if the person issues "rm *" or "rm *.*", it will do a confirmation, whether
    to proceed besides echoing "Alert, you're in `pwd`, confirm to proceed? "


Any other way to prevent accidental deletion of files are welcome.

I'm concerned that if I replace the "rm" binary with the above "rm" script,
certain cron or jobs may fail
sunhuxAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

TintinCommented:
On most Linux systems, rm is an alias to 'rm -i', which can be a great help in preventing the accidental deletion of files/dirs

Note that there is no simple way of detecting whether a user types in rm * as shell globbing will expand * to whatever files/dirs it matches.

0
nanocosmCommented:
If your default shell is for example bash, then you can assign an alias for rm. Cron usually has sh as the default shell and would not be affected by the alias.

Modify your profile (user or system wide) like this:
...
alias rm="rm -I"    (If you want to force to be asked when deleteing more than three files or recrusivly)
...

or for the bash script variant:
alias rm="PATH/TO/THE/BASHSCRIPT"


The korn shell script will be added shortly...
0
arnoldCommented:
You could alternative replace the rm binary with a shell script that will evaluate what is being passed and then pass the command/argument to the rm.real $arguments.

#!/bin/sh
echo "$0 is the command"
echo "$1 is the first argument"
echo "$2 is the second item"

save this file locally as rmtest.sh
then run: ./rmtest.sh -r
0
CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

Daniel VegaCommented:
The solution is not as simple as it seems because the rm utility is used also by other OS subsystems and to profanate them is not adviced.

Have you considered using a RESTRICTED shell?
0
nanocosmCommented:
Ok, here's the announced bashrc script. Place it in the global or user .bashrc and make sure your users are using bash as  a shell.


myrm () {
    rm=`which rm`
    p=`pwd`
    pathes=( /root /etc /var )
    #echo "CurrentPath: $p"
    #echo "Array: ${pathes[@]:0}"
    #echo "Elements: $(seq 0 $((${#pathes[@]} -1)))"
    #echo "$1 $2 $3"

    #This is case a)
    #if the person issues "rm -r *", the script will check if the current directory
    #is / or /var or /usr or /oracle (or any additional directories that I may add
    #from time to time),  it will not echo out a message, you are about to execute
    #a dangerous delete from `pwd` & then come back to command prompt
    if [ "$1" == "-r" ]; then
        for i in $(seq 0 $((${#pathes[@]} -1)))
        do
            #echo "Elem: ${pathes[$i]}"
            if [ "${pathes[$i]}" == "$p" ]
            then
                return  # Just do nothing
            fi
        done
    fi

    #This is case b)
    #if the person issues "rm *" or "rm *.*", it will do a confirmation, whether
    #to proceed besides echoing "Alert, you're in `pwd`, confirm to proceed? "
    if [ "$1" == "*" ] || [ "$1" == "*.*" ]; then
        for i in $(seq 0 $((${#pathes[@]} -1)))
        do
            #echo "Elem: ${pathes[$i]}"
            if [ "${pathes[$i]}" == "$p" ]
            then
                echo "*** WARNING ***"
                echo ""
                echo "You are in a path that is dagerous to modify!"
                read -p "Type 'YES' to continue : " a
                if [ "$a" == "YES" ]; then
                    $rm $1 $2 $3 $4 $5 $6 $7 $8 $9
                fi
            fi
        done
    fi
}

alias rm="myrm"

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
TintinCommented:
nanocosm.

The line

if [ "$1" == "*" ] || [ "$1" == "*.*" ]; then

will only work if shell globbing is turned off, or the user types

rm '*'

or

rm '*.*'

Also, either with shell globbing on or off

$rm $1 $2 $3 $4 $5 $6 $7 $8 $9

will not remove the files matched by * or *.*

Additionally, you can easily get away with not using an array, by doing

paths="/root|/etc|/var"

if echo $PWD | grep -qE "$paths"
then
      ...
fi




0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Shell Scripting

From novice to tech pro — start learning today.