1. Computer problem? Tech Support Guy is completely free -- paid for by advertisers and donations. Click here to join today! If you're new to Tech Support Guy, we highly recommend that you visit our Guide for New Members.

Shell scripting help

Discussion in 'Linux and Unix' started by evilmrhenry, Oct 17, 2003.

Thread Status:
Not open for further replies.
Advertisement
  1. evilmrhenry

    evilmrhenry Thread Starter

    Joined:
    Dec 14, 2001
    Messages:
    105
    First, the background.
    I'm running on a slackware based system, KDE 3.1.

    Whenever I want to delete something, I have a choice of sending it to the trash, or deleting it immediately. I don't like the trash, as I have to keep in mind to empty it regularly. Therefore, I have a *bad* habit of simply deleting the item.

    The following code (hopefully) will go through the trash and delete anything that was placed in there over 180 minutes (3 hours) ago. I plan to place it in the cron-hourly directory.

    Code:
    #! /bin/sh
    cd $HOME/Desktop/Trash/
    rm | find -amin +180 -not -name .directory -not -name .
    exit 0
    My questions:
    Will this work?
    Can bad things happen if I put this in?
    Did I forget something?

    Normally, I would just put this in, and try it out. However, the presence of rm makes me really want to get advice first.
     
  2. Squashman

    Squashman Trusted Advisor

    Joined:
    Apr 4, 2003
    Messages:
    19,783
    Well you could always use the rm -i option. Which is interactive and will prompt you if you wan to delete anything. That way you could test it out without destroying anything.
     
  3. evilmrhenry

    evilmrhenry Thread Starter

    Joined:
    Dec 14, 2001
    Messages:
    105
    Thanks for the tip. This version appears to work better:

    Code:
    #! /bin/sh
    cd $HOME/Desktop/Trash/
    find -amin +120 -not -name .directory -not -name . -exec rm -i {} \;
    exit 0
    Are there any filenames that could trigger bad reactions? Any other issues?
    (I'll remove the -i when I put it into action.)
     
  4. codejockey

    codejockey

    Joined:
    Feb 11, 2002
    Messages:
    1,405
    If I understand what you're trying to do, you may be able to simplify your script somewhat by using: find -amin +120 -type f -exec rm (etc.). This specifies that only files (not directories) should be removed. If you intend to remove (sub-) directories in Trash, then you should use rm -r (possibly rm -rf) instead of just rm in your -exec command (e.g., find -amin +120 -exec rm -rf {} \;). Note that this will not remove the current or the parent directory (. or ..).

    You might also consider having the script support two modes (readonly and execute); this would allow you to test/debug the script without risking unintentional removal of files. You could, for example, use something like:
    Code:
    #! /bin/sh
    USAGE="`basename $0` [-r]"
    READONLY=ON
    
    while [ ! -z "$1" ]
    do
        case "$1" in
            "-r")  READONLY=
                   shift
                   ;;
               *)  echo "$USAGE"
                   exit 1
                   ;;
        esac
    done
    
    if [ -z "$READONLY" ]
    then
        COMMAND="find -amin +120 -type f -exec rm {} \;"
    else
        COMMAND="find -amin +120 -type f"
    fi
    
    cd $HOME/Desktop/Trash
    eval "$COMMAND"
    
    This script defaults to "readonly" mode, and produces a list of files that would be removed (but doesn't remove them). Adding the -r option on the command line forces the script to perform the actual removal.

    One additional point: if you intend to use the script in a cron job, you should make provisions for handling any output from the script (error messages, etc.). If you do not redirect output, it will be mailed to you (which may be what you want if you are running the script readonly -- this would allow you to watch what the script would do with real data over time, without the risk of deleting an important file).

    Hope this helps.
     
  5. evilmrhenry

    evilmrhenry Thread Starter

    Joined:
    Dec 14, 2001
    Messages:
    105
    I'm beginning to have second thoughts about the script as it works now. I'm wondering how this one stands up instead:

    Code:
    #! /bin/sh
    cd $HOME/Desktop/Trash/
    rm -ri .countdown/*
    find -not -name .directory -not -name . -not -name .countdown -maxdepth 1 -exec mv -i {} .countdown \;
    exit 0
    (No, I didn't get the two lines switched. The second command moves the files, an hour passes, then the first line removes them.)

    Would it be better to move all files to a specific directory, then delete them, or would it be better to go by the access date?


    Some points:
    It needs to act on both files and dirs.
    However, only the files/dirs in the root directory of the Trash need to be looked at.


    I'll think about adding a read-only/working switch later. Right now, it's staying in confirmation mode.

    I need a bit more help on the output files. I tried
    Code:
    #! /bin/sh
    cd $HOME/Desktop/Trash/
    rm -ri .countdown/* > t_log.txt
    find -not -name .directory -not -name . -not -name .countdown -maxdepth 1 -exec mv -i {} .countdown \; >> t_log.txt
    exit 0
    
    but that just produces a blank file. Is this working the way it should? Is there a way to record the files being moved or deleted?

    Thanks for all your help.
     
  6. codejockey

    codejockey

    Joined:
    Feb 11, 2002
    Messages:
    1,405
    You can use your find command to create a list of the files and directories that will be removed. If you capture the output in a temporary file, you can remove each entry individually and email the file to yourself as a record of what happened. Would something like this do what you intend?
    Code:
    #! /bin/sh
    FINDLOG=/tmp/findlog.$$
    cd $HOME/Desktop/Trash
    find -not -name .directory -not -name . -not -name .countdown -maxdepth 1 > $FINDLOG
    
    for i in `cat $FINDLOG`
    do
        rm -rf $i
    done
    
    mail -s "list of files removed on `date`" user-name < $FINDLOG
    rm -f $FINDLOG
    
    I'd recommend against storing the files to be removed in another directory, and depending on a later execution of the script to remove them.

    Hope this helps.
     
  7. evilmrhenry

    evilmrhenry Thread Starter

    Joined:
    Dec 14, 2001
    Messages:
    105
    Just about.

    I changed a few things, to make it fit in better. Basically I changed the notification from a mail to just a file placed in the Trash, (I don't use the mail feature.) and used the correct find command. (You were using the "directory" method, not the "date" method.)
    Code:
    #! /bin/sh
    FINDLOG=$HOME/Desktop/Trash/.findlog
    cd $HOME/Desktop/Trash/
    find -not -name .directory -not -name .findlog -not -name . -maxdepth 1 -amin +180 > $FINDLOG
    
    for i in `cat $FINDLOG`
    do
        rm -rf $i
    done
    
    exit 0
    Unless there are any bugs, I'll go with this version. Thanks for your help, everyone!
     
  8. Sponsor

As Seen On
As Seen On...

Welcome to Tech Support Guy!

Are you looking for the solution to your computer problem? Join our site today to ask your question. This site is completely free -- paid for by advertisers and donations.

If you're not already familiar with forums, watch our Welcome Guide to get started.

Join over 733,556 other people just like you!

Thread Status:
Not open for further replies.

Short URL to this thread: https://techguy.org/172542

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice