parameters: | |
linux: | |
system: | |
profile: | |
# script provides sudoon & sudooff commands, allows working as-if root while tracking all commands | |
autosudo.sh: | | |
#!/bin/bash | |
# USAGE: $ . autosudo.sh | |
# $ sudoon | |
# $ sudo: <any commands> | |
# $ sudo: ... | |
# $ sudo: sudooff | |
# LIMITATIONS: | |
# - does not check your sudo policy, assumes "bash -c ..." is allowed | |
# - autocompletion (tab) for files/dirs does not work in restricted folders | |
# - may contain bugs | |
# NOTES: supports "cd ..."; allows to freely operate in restricted directories | |
function sudoon () { | |
if [ -z "$PREEXEC_PROMPT" ] | |
then | |
trap - DEBUG | |
ORIGINAL_PROMPT_COMMAND="$PROMPT_COMMAND" | |
PREEXEC_PROMPT=1 | |
ORIGINAL_PS1=$PS1 | |
PS1=$ORIGINAL_PS1"sudo: " | |
shopt -s extdebug | |
PROMPT_COMMAND="_preexec_prompt" | |
trap "_preexec_sudo" DEBUG | |
fi | |
} | |
function sudooff () { | |
trap - DEBUG | |
shopt -u extdebug | |
unset PREEXEC_PROMPT | |
PS1=$ORIGINAL_PS1 | |
unset SUDO_DIR | |
PROMPT_COMMAND="$ORIGINAL_PROMPT_COMMAND" | |
unset ORIGINAL_PROMPT_COMMAND | |
} | |
function _preexec_prompt() { | |
trap - DEBUG | |
PREEXEC_PROMPT=1 | |
trap "_preexec_sudo" DEBUG | |
} | |
function _preexec_sudo() { | |
# echo PREEXEC_PROMPT=$PREEXEC_PROMPT BASH_COMMAND=$BASH_COMMAND SUDO_DIR=$SUDO_DIR | |
[ -n "$COMP_LINE" ] && return | |
[ "$BASH_COMMAND" == "$PROMPT_COMMAND" ] && return | |
[ -z "$BASH_COMMAND" ] && return | |
[[ "$BASH_COMMAND" =~ ^exit$|^set\ |^shopt\ |^trap\ |^sudoon$|^sudooff$ ]] && return | |
[ -z "$PREEXEC_PROMPT" ] && return | |
if [ "$PREEXEC_PROMPT" -eq 0 ]; then | |
# echo cancelling "$BASH_COMMAND" | |
return 1 | |
fi | |
# echo "trap-DEBUG" | |
trap - DEBUG | |
PREEXEC_PROMPT=0 | |
FULL_COMMAND=$(HISTTIMEFORMAT='' history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//") | |
# echo "Running _preexec_sudo $FULL_COMMAND" | |
ARG_0=$(cut -d' ' -f1 <<< "$BASH_COMMAND") | |
TYPE=$(type "$ARG_0" 2> /dev/null | head -n 1) | |
if [[ ! "$TYPE" =~ / ]] | |
then | |
if [ "$BASH_COMMAND" == "$FULL_COMMAND" ] | |
then | |
if [[ "$BASH_COMMAND" =~ ^cd\ ]] | |
then | |
if [ -z "$SUDO_DIR" ] | |
then | |
if $BASH_COMMAND 2> /dev/null | |
then | |
trap "_preexec_sudo" DEBUG | |
return 1 | |
else | |
DIR=$(sudo bash -c "$BASH_COMMAND; pwd") | |
DIR_ERR=$? | |
fi | |
else | |
DIR=$(sudo bash -c "cd $SUDO_DIR; $BASH_COMMAND; pwd") | |
DIR_ERR=$? | |
fi | |
if [ "$DIR_ERR" -eq 0 ] | |
then | |
if cd "$DIR" 2> /dev/null | |
then | |
SUDO_DIR='' | |
PS1=$ORIGINAL_PS1"sudo: " | |
else | |
SUDO_DIR=$DIR | |
[ -n "$SUDO_DIR" ] && PS1_SUDO_DIR="($(echo "$SUDO_DIR" | rev | cut -d'/' -f1 | rev))" || PS1_SUDO_DIR='' | |
PS1=$ORIGINAL_PS1"sudo$PS1_SUDO_DIR: " | |
fi | |
fi | |
trap "_preexec_sudo" DEBUG | |
return 1 | |
elif [ -z "$SUDO_DIR" ] | |
then | |
trap "_preexec_sudo" DEBUG | |
return # single call to function / builtin; not sudoing | |
fi | |
fi | |
fi | |
[[ "$TYPE" =~ / ]] && [ "$(which "$ARG_0")" == "$(which sudo)" ] && return 0 # execute explicit sudo as-is | |
if [ -n "$SUDO_DIR" ] | |
then | |
CMD_DIR="cd $SUDO_DIR; " | |
else | |
CMD_DIR='' | |
fi | |
if [ ! "$BASH_COMMAND" == "$FULL_COMMAND" ] || [ -n "$CMD_DIR" ] | |
then | |
# echo combined or cd command: `printf '%q' "$CMD_DIR$FULL_COMMAND"` | |
eval sudo -E bash -c $(printf '%q' "$CMD_DIR$FULL_COMMAND") | |
else | |
eval sudo -E $FULL_COMMAND | |
fi | |
trap "_preexec_sudo" DEBUG | |
return 1 | |
} |