Shell Tricks

Delete all files created after a certain time

22 Mar 2015

I want to find and delete all files after 11:19am, 18 March, 2015 in the current dir.

$ touch -t "201503181119" after

Now I have a file named "after" whose creation time is 11:19am, 18 March, 2015.

$ ls -l after
-rw-rw-r-- 1 mwood mwood    0 Mar 18 11:19 after

Now find and delete any files older than this file:

$ find . -newer after -exec rm -rf {} \;

Send mail from a shell script on exit/death

The -e setting in bash is fantastic: die on the first command that fails to return 0 (success). We can couple this with the trap command to trap the EXIT signal when the script exits, and automatically send an e-mail when the script exits.

#!/bin/bash

set -e

#export EMAIL_RECIPIENTS="mwood@somesoftware.com someoneelse@somesoftware.com someoneelse2@somesoftware.com"
export EMAIL_RECIPIENTS="mwood@somesoftware.com"
export SEND_EMAIL="true"

# call like this:
# send_email "this is the subject" "this is the message"
send_email() {
    if [ -z "${SEND_EMAIL}" ]; then
        return
    fi

    local subject=$1
    local msg=$2

    if [ -z "$subject" ]; then
        msg="no subject"
    fi

    if [ -z "$msg" ]; then
        msg="no message"
    fi

    cat << EOF | fmt | mail -s "$subject" $EMAIL_RECIPIENTS
The blah script says:
$msg
EOF
}
trap "echo 'I die'; send_email 'this is the subject' 'this is the message'" EXIT HUP INT QUIT TERM

# send_email 'this is the subject' 'this is the message'

ls ./var
ls ./baz  # this dir does not exist, so -e makes us stop, and trap sends an e-mail; nice!
ls ./src

Remove a file that starts with a hyphen

rm ./-rf

Use ex to remove the first line of a file:

ex -c d -c w -c q file.txt

Recursively remove empty directories:

rmdir `find . -type d -print`

This command takes advantage of the fact that rmdir will refuse to delete any non-empty directory. Note that you will have to run this comand a few times if, by removing one empty directory, you have left its parent empty.

Change permission on all 664 files to 600:

find . -perm 644 -exec chmod 600 {} \;

Find all TODOs in a codebase (*.java files in this example):

find . -name '*.java' -exec grep -i -H -n "todo" {} \;