|
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
|
Re: [PLUG] Interactive rm
|
In the message dated: Wed, 01 Feb 2006 12:20:09 EST,
The pithy ruminations from morgan on
<Re: [PLUG] Interactive rm> were:
=> Art,
=>
=> If you're using bash you would create an alias:
=>
=> alias rm="rm -i"
In the simplest case, yes. However, the original posted requested a slightly
different behavior, as in:
if there are multiple arguments to rm, then run rm interactively
if there is a single argument to rm, then run rm non-interactively
This is not as trivial as it appears. While it's easy to count the number of
arguments and call "rm -i" if there's more than one argument, this doesn't deal
correctly with arguments that are options, not the targets of the rm command.
In addition, rm is sensitive to the order of arguments, and it's easy to get
unexpected results when combining "-f" and "-i". I'm also skipping over the
issues with targets that have embedded whitespace in their names...
=>
=> That will only affect the current shell. In Fedora Core and probably
=> other linuxes you would vi /etc/bashrc and add alias rm="rm -i" to the
=> bottom.
IMHO, I'd strongly suggest not changing /etc/bashrc. That is the system-wide
configuration file for bash, and making the change there perpetuates the
problem of hiding how rm really works. Personally, I'd make the change to
$HOME/.bashrc, on a per-user basis, with a heavily commented description of
what the alias does.
=>
=> Changes to /etc/bashrc don't affect running shells. You're best to
=> logout completely to make sure it takes effect everywhere.
=>
=> -morgan
=>
=>
=>
=> Art Alexion wrote:
=> > When I first started using Linux about 5 years ago, "rm *" defaulted to
=> > "rm -i *".
Gack! Bad, bad linux :) . There's a pedantic, but important, educational issue
here. The "rm" command does not default to interactive use. In some linux
distributions, the choice was made to alias the rm command to include the
interactive option. This is common, and transparent to most users. The problem,
as Art found out (the hard way), is that this is not really the default behavior,
nor is it universal across distributions or *nix varients.
This behavior could be particularly problematic if, for example, you're using a
different shell to do filesystem recovery, and you expect that "rm" will be
interactive.
I'm somewhat in favor of "rm -i", but when I was teaching Unix classes, I'd
begin with demonstrations of "rm" in it's normal mode, then introduce the use
of aliases, and leave the choice up to the educated students. Hiding this
distinction only causes trouble later...
=> >
=> > I just clumsily deleted all of the files in a directory with the numpad
=> > -- trying to type "*.flac", I hit the enter key with the side of my
=> > finger slightly before it hit the "." key.
=> >
=> > How can I restore rm's default behavior so that "rm *" requires
=> > confirmation, but "rm specified_file" does not?
Here's a bash shell function that will do what you want. This fragment of code
can be put in your ~/.bashrc file. Note that the function, as named, will work
when called as "myrm". You can change this to "rm" and therefore hide how "rm"
really behaves.
------------------------------------------------------------------------------
function saferm
{
# Shell function to call rm interactively if there are multiple
# non-option arguments to rm. This is somewhat complicated due
# to the need to separate option arguments from targets,
# and for the need to deal with the special case of the "--"
# argument.
#
# $Header: /home/bergman/Bin/RCS/saferm,v 1.2 2006/02/01 18:11:57 bergman Exp bergman $
#
# Copyright 2006, Mark Bergman
# bergman@merctech.com
# Released under the GNU GENERAL PUBLIC LICENSE, Version 2
targetcount=0
targets=""
options=""
for arg in $*
do
case $arg in
--)
# signifier of last option argument,
# successive filename arguments may begin with
# a "-", so copy all remaining arguments into the
# list of targets
temp=`echo $* | sed -e "s/.* -- //"`
targets="$targets $temp"
targetcount=$((targetcount + 1))
last
;;
-*)
# We have an option argument...
options="$options $arg"
;;
*)
# non-option argument...copy it into the
# list of file/directory names
#
# Note: this will probably break (badly)
# if used with filenames with embedded
# whitespace. It's possible to munge IFS
# to get around some of that...
targets="$targets $arg"
targetcount=$((targetcount + 1))
;;
esac
done
if [ $targetcount -gt 1 ]
then
# Note: this weirdness is due to the fact that rm applies
# option arguments in the order that they are found, with
# successive arguments overriding previous ones. Thus, if
# one of the arguments is "-f" (force non- interactive),
# then the "-i" must be the last argument
/bin/rm $options -i $targets
else
/bin/rm $*
fi
}
------------------------------------------------------------------------------
Mark
----
Mark Bergman
bergman@merctech.com
Seeking a Unix/Linux sysadmin position local to Philadelphia or via telecommuting
http://wwwkeys.pgp.net:11371/pks/lookup?op=get&search=bergman%40merctech.com
___________________________________________________________________________
Philadelphia Linux Users Group -- http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion -- http://lists.phillylinux.org/mailman/listinfo/plug
|
|