1829913 Members
2969 Online
109993 Solutions
New Discussion

rm -fr *

 
SOLVED
Go to solution
Preetam
Occasional Advisor

rm -fr *

Hi, i accidently typed "rm -fr *" and this deleted my whole home directory. Fortunately I had a backup and restored it. Since this fiasco I sat down to write a script(rem in c shell) for detecting "rm" combined with "*". My problem is when i use * as arguement in cmd line for the script it expands to the all the files in the current directory ( an echo of number of arguements for rem * does not give 1 but evaluates to number of files in the directory). How do I detect a special char (like *) passed as an arguement from cmd line??
22 REPLIES 22
Peter Godron
Honored Contributor

Re: rm -fr *

Hi,
what are you trying to achieve with your script? You can alias rm to rm -i to build a double protection against accidential delete.
I assume your script is going to replace the normal rm command and give a warning if the "*" is used ?
Please give more background.
(Congratulations on having a good backup !)
Preetam
Occasional Advisor

Re: rm -fr *

Yup, your assumption is correct. I basically want to write a script for detecting a "*" with rm cmd. That, as you said, can be achieved with the rm -i alias which will also create problems if I want to delete a set of files *.xyz anytime. Right now I am trying to learn scripting so I use scripts for all the things I can think of (this being one of them). So if in future I want to detect a "*" in any of my scripts how do I do it? basically how do I bypass the "*" expansion functionality of the OS before it is passed to the script?
I would be happy to clarify any more queries.
Peter Godron
Honored Contributor

Re: rm -fr *

Hi,
a file * can be removed via
rm "*" or rm \* (no spaces)

$ touch *
$ ll
total 0
-rw-rw-rw- 1 gp users 0 Aug 11 10:14 *
$ rm "*"
$ ll
total 0
$ touch *
$ ll
total 0
-rw-rw-rw- 1 gp users 0 Aug 11 10:15 *
$ rm \*
$ ll
total 0
Eric SAUBIGNAC
Honored Contributor

Re: rm -fr *

Hi,

As it is the shell which processes carateres *, you would have to modify the shell itself !

You cannot replace the command rm by a script asked to handle carateres * because it will receive the list of the files of the current directory : shell behavior.

I think there is no simple answer to your question unless you rewrite C-Shell
RAC_1
Honored Contributor

Re: rm -fr *

move rm binary somewhere and put a following script as "rm". Please note that any patches that patch rm binary will overwrite rm script.

(not tested fully. So double check before you use it)
#/usr/bin/ksh
first=$(echo ${1}|tr -cd '\*'|cut -c1)
if [ ${first} = "\*" ];then
echo "you have used "\*" in rm command!!1 Will exit now.\n"
exit 1
done


We also need to add more error checking to see if any of the args has "*" and not just first arg.
There is no substitute to HARDWORK
Preetam
Occasional Advisor

Re: rm -fr *

Interesting!!
Peter,
The idea of using a \* or a "*" did occur to me. But it kinda defeats the purpose of checking for a wildcard since if I am careful enough to write a \* then I will be careful enough not to delete my home dir.

Eric,
Your explanation is very plausible. But as gurus of UNIX say "there is always another way of doing it". There must be some other way apart from editing the shell.

Rac,
I tried the code given. There were some errors. (I use csh by force of requirement but for this I did switch to ksh for once and i have no idea of ksh syntax!!). A blind copy-paste-run of the script gives syntax error: `done' unexpected.
also after I comment out done it gives me a sdyntax error: `then' unmatched.
can you give the same for csh??
RAC_1
Honored Contributor

Re: rm -fr *

I am not very comfortable with csh. I modified the code. Please check.

#/usr/bin/ksh
first=$(echo ${1}|tr -cd '\*'|cut -c1)
if [ ${first} = "\*" ];then
echo "you have used "\*" in rm command!!1 Will exit now.\n"
exit 1
fi


Again, this code checks if first argument to rm has "*" in it or not. Ideally, what you need is code that checks all arguments to rm and if any of those arguments has "*" or not.
There is no substitute to HARDWORK
Preetam
Occasional Advisor

Re: rm -fr *

#/usr/bin/ksh OR #! /bin/ksh OR #! /usr/bin/ksh
first=$(echo ${1}|tr -cd '\*'|cut -c1)
if [ ${first} = "\*" ];then
echo "you have used "\*" in rm command!!1 Will exit now.\n"
exit 1
fi

This code gives another type of error. it says test: arguement expected. even when i type "rem *" rem being the script name. even a valid filename insted of * gives the same error. :(
RAC_1
Honored Contributor

Re: rm -fr *

Now I see it. It's going to be difficult than I thought. Before you do anything to work out that the command argument has "*" in it, shell expands it. So we want a shell not to expand it before we do our check. Quite difficult....
There is no substitute to HARDWORK
James R. Ferguson
Acclaimed Contributor
Solution

Re: rm -fr *

Hi Preetam:

In the Posix shell if you want to disable file name generation, simply do:

# set -f

Compare this:

# set +f
# echo *
# set -f
# echo *

Regards!

...JRF...
Eric SAUBIGNAC
Honored Contributor

Re: rm -fr *

no ????????
Eric SAUBIGNAC
Honored Contributor

Re: rm -fr *

Sorry my amused "no ???" was for RAC as i said the same thing a little earlier ...

Yes, James, you are right with posix shell but preetam wants to work with C-shell. I don't practice c-shell but i did not hear of same behavior that set -/+f with posix shell

Anyway, i could never work with shell without character expansion. Ok, you can do some big mistake but it's life ;-) Anyway Peter's suggestion to make an alias to rm -i is a good protection.
James R. Ferguson
Acclaimed Contributor

Re: rm -fr *

Hi (again) Folks:

In the 'csh' you can use 'noglob' to disable file name expansion.

Users of 'csh' might want to read this:

http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/

Barring any shell preferences, on HP-UX you cannot change root's default shell from other than '/sbin/sh' since to do so leads to an unbootable system. That said, one would do well to understand the ramifications of file name expansion in the Posix shell, and be extra careful typing 'rm -f' under all conditions!!!

Regards!

...JRF...
Preetam
Occasional Advisor

Re: rm -fr *

James that was a very useful bit of info... it works in ksh too... but sadly not in csh...
trying to work it into a script...

eric, i have to work in csh coz my repository has all the required scripts in csh else i would ve preffered a different shell...

Please do keep me posted abt any brainstorms regarding this on csh...
Jonathan Fife
Honored Contributor

Re: rm -fr *

Rather than making the shell not expand *, I would do a check to see if the arguments passed match the contents of the current directory. Something like
wildcard=1
for file in $(echo *); do
if [ $(echo " $* " | grep -c " $file ") -ne 1 ]; then
wildcard=0;
break;
fi;
done

echo "used wildcard? $wildcard"

Heavy-handed, but it should work.
Decay is inherent in all compounded things. Strive on with diligence
James R. Ferguson
Acclaimed Contributor

Re: rm -fr *

Hi Preetam:

"Globbing" is the real term for filename expansion using wildcards. Now, you should be able to remember that in 'csh' you set 'noglob' to disable it :-))

See the manpages:

http://docs.hp.com/en/B2355-60127/csh.1.html

By the way, while aliasing 'rm' to 'rm -i' is an extra layer of protection in an interactive shell, anytime you type 'rm -f' you override the '-i' switch.

Regards!

...JRF...
spex
Honored Contributor

Re: rm -fr *

Preetam,

You may also want to think about implementing a staging area for files pending deletion (a la "Trash" or "Recycle Bin"). Move the 'rm' binary somewhere safe and replace it with a script that moves files to a secure staging area. Make sure the script accounts for large files (perhaps by deleting them outright instead of moving them). Then cron a clean up job to purge the staging area.

PCS
Peter Nikitka
Honored Contributor

Re: rm -fr *

Hi,

the following will work in TCSH but not in csh,
because csh won't deal with then parameters 'argn' supplied to

source filename arg1 arg2 ...

cat ~/bin/mec
#!/usr/bin/tcsh # just for syntax highlighting
if ("$argv[1]" == '*') then
echo I see a star
else
echo $*
endif

Set this alias:
alias myecho ~/bin/mec

Now entering
myecho *

will lead to the above message, anything else will return the shell-expanded arguments.

Adopting for a rm-lile solution is trivial.

NB: TCSH only!

mfG Peter
The Universe is a pretty big place, it's bigger than anything anyone has ever dreamed of before. So if it's just us, seems like an awful waste of space, right? Jodie Foster in "Contact"
Bill Hassell
Honored Contributor

Re: rm -fr *

It will be impossible to protect from rm -fr using wrapper scripts. You happened to type * but it would be 1000 times more disastrous if you typed rm -fr / (which wipes the disks clean). It could also be a spelling error where a space got accidently put into a pahname like:

rm -fr /var /tmp/myfiles*

In this case, the accidental space just started rm removing the entire /var directory (a disaster since all installed patches and HP product histories are now gone).

So a wrapper won't work. Instead, alias the dangerous commands rm mv and cp to:

alias rm="/usr/bin/rm -i"
alias mv="/usr/bin/mv -i"
alias cp="/usr/bin/cp -i"

-i forces these commands to ask permission for each file or directory that will be destroyed.

Now unfortunately this only helps when you don't use the -f option which overrides -i. Here is where a wrapper script would help. Use getopts to process all the possible option combinations and disallow -f. You can rename the real binaries like rm to something like rm.real, etc. then have your wrapper script implement -i for everything. For knowledgeable users, they can use the real binaries. Note that all users must have the above aliases so they don't use any shell builtin commands.


Bill Hassell, sysadmin
KapilRaj
Honored Contributor

Re: rm -fr *

RAC, No !!! don't move the rm binary somewhere and replace it with a script. no good idea to me.
Nothing is impossible
Preetam
Occasional Advisor

Re: rm -fr *

thanks all you guys... got a lot of info from your replies... fantastic!!
Peter Nikitka
Honored Contributor

Re: rm -fr *

Fine for you, Preetam,

that you got a lot of fantastic replies!
If I could see these fantastic replies awarded with points, it would be a motivation for the responders, to do that for further questions as well.
If a problem is not solvable in a way you want it to be solved, it's not a reason to give few points (or assign nothing), IMHO.

mfG Peter
The Universe is a pretty big place, it's bigger than anything anyone has ever dreamed of before. So if it's just us, seems like an awful waste of space, right? Jodie Foster in "Contact"