Autosudo
If you're condemned to use sudo for systems administration on a daily basis you know the problem: working all the time with sudo is annoying. It's ok if you've got to enter sudo only here and there. But on some systems almost everything is only reachable via sudo.
At least it annoyed me, so I put the nightmare to an end. Autosudo consists of a couple of bash functions which - once enabled - learn each entered sudo command and create a temporary wrapper function for it so that you can leave "sudo" the next time you use the command. An example session:
[16.Jul 09:48:22] --- [~] --- me@machine: % autosudo ena[16.Jul 09:49:14] — [~][autosudo] — me@machine: % sudo less /var/log/splunk/ticket.log [..]
+++ autosudo: added “less” to auto sudo commands +++
[16.Jul 09:50:32] — [~][autosudo+1] — me@machine: % less /var/log/splunk/ticket.log
[16.Jul 09:50:50] — [~][autosudo+1] — me@machine: % autosudo sh +++ auto sudo enabled for: less +++
[16.Jul 09:50:52] — [~][autosudo+1] — me@machine: % autosudo dis +++ disabling auto sudo commands +++ disabling less
[16.Jul 09:50:58] — [~] — me@machine: % less /var/log/splunk/ticket.log /var/log/splunk/ticket.log: Permission denied
What happens here? First, I enabled the feat with "autosudo ena". Next I called a sudo command "sudo less". Once completed the autosudo facility adds "less" as an autosudo wrapper and notifies me about it. From now on I can just use "less" instead of "sudo less" while achieving the same functionality. Finally I let it display a list of currently autosudo'ed commands ("autosudo sh") and then I disable it with "autosudo dis". Note that the plain "less" call in the end doesn't work anymore since after disabling autosudo "less" was not sudo wrapped anymore. Easy enough.
Here's the code:
autosudo () { # enable auto sudo case $1 in e|ena|enable) export AUTOSUDO=1 export SUDOCMD=`type -p sudo` alias sudo=sudoexec ;; d|dis|disable) unset AUTOSUDO unalias sudo echo "+++ disabling auto sudo commands +++" for cmd in $AUTOSUDOCMDS; do echo " disabling $cmd" unset $cmd done ;; s|sh|show|status) if test -n "$AUTOSUDO"; then echo "+++ auto sudo enabled for: $AUTOSUDOCMDS +++" else echo "+++ auto sudo disabled +++" fi ;; *) echo "Usage: autosudo <enable|disable|show>" ;; esac }sudoexec () { # determine sudo cmd and if successfull, alias it away if test -n “$AUTOSUDO”; then if $SUDOCMD $; then cmd=
echo "$*" | awk '{ print $1}'
if echo “$cmd” | egrep -v “^-” > /dev/null 2>&1; then lambda="/tmp/.lambda.bash.$$" cmd=basename $cmd
cat <<EOF > $lambda unalias $cmd function $cmd () { $SUDOCMD $cmd $ } EOF export LAMBDA=$lambda AUTOSUDOCMDS="$AUTOSUDOCMDS $cmd" echo echo “+++ autosudo: added "$cmd" to auto sudo commands +++” echo fi fi fi }cleanlambda() { if test -n “$LAMBDA”; then rm -f $LAMBDA LAMBDA="" unset LAMBDA fi } PROMPT_COMMAND=“if test -n "$LAMBDA"; then source $LAMBDA; cleanlambda; fi; PS1=’[\033]0;\u@$host:\w\007] $(DATE) — [\w]$(SHAUTOSUDO)$(JOBS) — \u@$host: $CURSOR ‘”
Some words about it: If you call "autosudo ena", then "sudo" will be made an alias to "sudoexec", one of the functions above. "sudoexec" then executes the sudo command as usual and if it returns success it extracts the command and puts it into a wrapper function which it writes into a temporary file. The filename gets exported into the variable $LAMBDA. The most important part is the extension to $PROMPT_COMMAND. I precede it with a little bit of code which looks for an environment variable $LAMBDA. If set it assumes it is a file and sources it. This makes the wrapper function available to the current bash environment.