Friday, May 25, 2007

Global Warming

Here's an extremely interesting video to watch:
The Great Global Warming Swindle
It makes a case for the following two statements:
  1. Yes, the Earth is obviously getting warmer
  2. No, humankind doesn't have all that much to do with it
It shows very convincing science which indicates man-made CO2 has nothing to do with global warming. It looks like we're just in it for the ride.

But, on the other hand, check out this link for a thorough debunking of the video.

Monday, May 21, 2007

Using bash functions under sudo

Update: Now on github

Have you ever done the following?

$ type duk
duk is a function
duk ()
{
   du -k "$@" | sort -n
}

$ sudo duk /tmp
sudo: duk: command not found
duk is a function that will show you directory sizes under a given pathname (or the current directory), nicely sorted by size, largest at the bottom just above your next prompt. It's very handy, put it in your .bashrc ;-). sudo doesn't know what to do with "duk" however, since it's not a system command. Therefore, I wrote a function that is a front-end to sudo. It parses the command line you give it, and expands any functions or aliases that you call. For bonus points, it shows you the full command line as the shell receives it before you type your password. Use it as follows:
$ source sudo.bash
$ sudo duk /tmp
/opt/local/bin/sudo -- bash -x -v -c duk ()
{
   du -k "$@" | sort -n
};"duk" '/tmp'
Password:
[...]
3648    /tmp/synergy-1.3.1/lib
6184    /tmp/synergy-1.3.1
20128   /tmp/prarora
1294048 /tmp/tmp
5304016 /tmp
Looks like I'll need to do some cleaning up in /tmp. Full source follows. To use it, place a source ~/.sudo.bash (for example) in your .bashrc after copying the code to your ~/.sudo.bash, or copy the full code to your .bashrc. Then, simply use sudo as you would before. This function handles all sudo arguments. There is one extra argument, -x, which expands arguments as you, not as root. This is needed in some corner cases. (Update: New version which no longer uses sed and handles spaces in sudo options!)
# Wrap sudo to handle aliases and functions
# Wout.Mertens@gmail.com
#
# Accepts -x as well as regular sudo options: this expands variables as you not root
#
# Comments and improvements welcome
#
# Installing: source this from your .bashrc and set alias sudo=sudowrap
#  You can also wrap it in a script that changes your terminal color, like so:
#  function setclr() {
#    local t=0               
#    SetTerminalStyle $1                
#    shift
#    "$@"
#    t=$?
#    SetTerminalStyle default
#    return $t
#  }
#  alias sudo="setclr sudo sudowrap"
#  If SetTerminalStyle is a program that interfaces with your terminal to set its
#  color.

# Note: This script only handles one layer of aliases/functions.

# If you prefer to call this function sudo, uncomment the following
# line which will make sure it can be called that
#typeset -f sudo >/dev/null && unset sudo

sudowrap () 
{
    local c="" t="" parse=""
    local -a opt
    #parse sudo args
    OPTIND=1
    i=0
    while getopts xVhlLvkKsHPSb:p:c:a:u: t; do
        if [ "$t" = x ]; then
            parse=true
        else
            opt[$i]="-$t"
            let i++
            if [ "$OPTARG" ]; then
                opt[$i]="$OPTARG"
                let i++
            fi
        fi
    done
    shift $(( $OPTIND - 1 ))
    if [ $# -ge 1 ]; then
        c="$1";
        shift;
        case $(type -t "$c") in 
        "")
            echo No such command "$c"
            return 127
            ;;
        alias)
            c="$(type "$c")"
            # Strip "... is aliased to `...'"
            c="${c#*\`}"
            c="${c%\'}"
            ;;
        function)
            c="$(type "$c")"
            # Strip first line
            c="${c#* is a function}"
            c="$c;\"$c\""
            ;;
        *)
            c="\"$c\""
            ;;
        esac
        if [ -n "$parse" ]; then
            # Quote the rest once, so it gets processed by bash.
            # Done this way so variables can get expanded.
            while [ -n "$1" ]; do
                c="$c \"$1\""
                shift
            done
        else
            # Otherwise, quote the arguments. The echo gets an extra
            # space to prevent echo from parsing arguments like -n
            while [ -n "$1" ]; do
                t="${1//\'/\'\\\'\'}"
                c="$c '$t'"
                shift
            done
        fi
        echo sudo "${opt[@]}" -- bash -xvc \""$c"\" >&2
        command sudo "${opt[@]}" bash -xvc "$c"
    else
        echo sudo "${opt[@]}" >&2
        command sudo "${opt[@]}"
    fi
}
# Allow sudowrap to be used in subshells
export -f sudowrap