bergman on 1 Feb 2006 18:14:36 -0000


[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