Best of Bash functions

statmonkey

Maybe this should be a new thread. My apologies if so. [edit- split off as new thread for you, thnx for suggesting that. - Digit]

With the recent posts on aliases I thought there might be some value in keeping with this thread to post something on functions and .bashrc.  My .bashrc is at present about 300 lines and use it for much more than just making sure my paths are right, etc.  I won't post the whole thing it includes a very detailed bash completion section which accounts for most of the size.  It also uses several functions which I am always looking to add so maybe this will prompt someone to post their favorites.  Functions work similarly to aliases except you can do a lot more with them.  I have three main functions which I use a ton:
# function to swap two files with each other:
#   swap file1.txt file2.txt this is used as shown with things like swap .conkyrc .conkyold etc.
function swap() # Swap 2 filenames around, if they exist
{ #(from Uzi's bashrc).
local TMPFILE=tmp.$$

[ $# -ne 2 ] && echo "swap: 2 arguments needed" && return 1
[ ! -e $1 ] && echo "swap: $1 does not exist" && return 1
[ ! -e $2 ] && echo "swap: $2 does not exist" && return 1

mv "$1" $TMPFILE
mv "$2" "$1″
mv $TMPFILE "$2"
}

if you play with it a little you will get the point. 

The next two are find functions with the second one allowing you to perform some action on what it finds.  SpaceFM has this feature but I really use the terminal far more than SpaceFM.
# Find a file with a pattern in name:
#  ff string.*
function ff() { find . -type f -iname '*'$*'*' -ls ; }

# Find a file with pattern $1 in name and Execute $2 on it:
#  fe string.* cmd
function fe()
{ find . -type f -iname '*'${1:-}'*' -exec ${2:-file} {} \; ; }


This last one is really my favorite.  It passes the $USERS bash history to root under su.  I always forget how to use !! correctly (not sure why, probably due to the fact I am an idiot) but frequently I type some command or set and then realize I should have been root.  This function fixes that issue and more.  It essentially is the core for some other things as well.  I created functions using this model to pass my aliases, etc.  It is written to work only under su not sudo su (for reasons that should be obvious) and I might be the only fool who runs root as root but I get a little old school I guess.  Anyway I use this and its little brothers fairly often and it has saved me a lot of work.  If you read it you will pretty quickly see how it could be adapted for sudo su with a few adjustments.  Most of you are much more intuitive than I am so I'll let you sort that out.
# set a function using su to have USER history available to root ONLY as su
# this also passes ICEauthority and vi history (which I seldom use)
# please remember the \ are only there to make it look nice as line ends
function su () {
    local SUUSER=root
    local ORIGU=$USER
    local ORIGG=`groups | awk '{print $1}'`
    if [[ $# -gt 0 ]] ; then
        local char=`echo $1 | cut -c 1`
        if [[ "$char" == '-' ]] ; then
            /bin/su $*
            return $?
        else
            local SUUSER=$1
        fi
    fi
    #append recent history to the history file
    history -a
    /bin/su ${SUUSER} -c "env USER=${SUUSER} HOME=${HOME} ${SHELL}; \
          [ -f ${HOME}/.ICEauthority ] \
          && chown $ORIGU:$ORIGG ${HOME}/.ICEauthority ${HOME}/.viminfo"
    # Clear the history list by deleting all the entries.
    history -c
    # Read the contents of the history file and use them as the current history.
    history -r
}

Disclaimer: I didn't write these originally.  I lifted them from those who have gone before me and later added children off them that do similar functions.  I do think they provide a good template of just some of the way you can use functions in bash and get more out of your bash environment.  BTW yes you can pass these to scripts and use them there as well.  Anyone out there use functions?  I would love to see them and hope this sparks something or helps someone.


statmonkey

#1
This may be only for my own records so I can find them if nothing else.  But maybe someone will use them.

I noticed when I was doing something that my extract routine was no longer working.  I don't have spacefm or thunar open often and do most of my work in terminator.  It is much faster for me to be able to just type "extract" hit tab a couple of times and extract whatever compressed file I want.  The following small function does just that (assuming you have your bash completion set up) when added to .bashrc

# The following function will extract a wide range of compressed files with syntax
# extract <file1> <file2> etc.
extract() {
    local c e i

    (($#)) || return

    for i; do
        c=''
        e=1

        if [[ ! -r $i ]]; then
            echo "$0: file is unreadable: \`$i'" >&2
            continue
        fi

        case $i in
            *.t@(gz|lz|xz|b@(2|z?(2))|a@(z|r?(.@(Z|bz?(2)|gz|lzma|xz)))))
                   c='bsdtar xvf';;
            *.7z)  c='7z x';;
            *.Z)   c='uncompress';;
            *.bz2) c='bunzip2';;
            *.exe) c='cabextract';;
            *.gz)  c='gunzip';;
            *.rar) c='unrar x';;
            *.xz)  c='unxz';;
            *.zip) c='unzip';;
            *)     echo "$0: unrecognized file extension: \`$i'" >&2
                   continue;;
        esac

        command $c "$i"
        e=$?
    done

    return $e
}


The next one is one I use all the time.  For many of the same reasons I don't want to open up geany or medit to capture an idea or prod myself to do something later.  It works simply.  Just type "note whatever you want to add" and it pumps it into notes in the docs directory or wherever you have set.  Typing "note" enter will print out what is in your note file and "note -c" will clear the notes file and let you start clean. Forgot one little section.  Adjust the editor as you see fit but to edit the note file typing "note -e" will pull the file up in nano.

# This is just a simple function to take notes.  You can just enter note (whatever you want)
# and it will append it to notes in home/documents but you can set it to go anywhere
note () {
    # if file doesn't exist, create it
    if [[ ! -f $HOME/documents/notes ]]; then
        touch $HOME/documents/notes
    fi

    if [[ $# -eq 0 ]]; then
        # no arguments, print file
        cat $HOME/documents/notes
    elif [[ "$1" == "-c" ]]; then
        # clear file
        echo "" > $HOME/documents/notes
    elif [[ "$1" == "-e" ]]; then
        nano $HOME/documents/notes
    else
        # add all arguments to file
        echo "$@" >> $HOME/documents/notes
    fi
}