From d05feb1f8ef82ec44e1de8cd77a74159a01b9106 Mon Sep 17 00:00:00 2001 From: Frederick Zhang Date: Sat, 21 Sep 2019 16:14:31 +1000 Subject: [PATCH 1/6] do_sudo: new sudo alias to handle alias expansion --- plugins/do_sudo/README.md | 6 ++++++ plugins/do_sudo/do_sudo.plugin.zsh | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 plugins/do_sudo/README.md create mode 100644 plugins/do_sudo/do_sudo.plugin.zsh diff --git a/plugins/do_sudo/README.md b/plugins/do_sudo/README.md new file mode 100644 index 000000000..1d1b9e7d5 --- /dev/null +++ b/plugins/do_sudo/README.md @@ -0,0 +1,6 @@ +# `do_sudo` plugin + +This plugin provides a sudo wrapper that handles alias expansion and avoids +being broken by `nocorrect` `noglob` from other aliases. + +Modified from the script by [Wayne Davison](https://www.zsh.org/mla/users/2008/msg01229.html). diff --git a/plugins/do_sudo/do_sudo.plugin.zsh b/plugins/do_sudo/do_sudo.plugin.zsh new file mode 100644 index 000000000..b59f3ac6a --- /dev/null +++ b/plugins/do_sudo/do_sudo.plugin.zsh @@ -0,0 +1,27 @@ +if [[ "$ENABLE_CORRECTION" == "true" ]]; then + alias sudo='nocorrect noglob _do_sudo ' +else + alias sudo='noglob _do_sudo ' +fi + +function _do_sudo() { + integer glob=1 + local -a run + run=( command sudo ) + while (($#)); do + case "$1" in + command|exec|-) shift; break ;; + nocorrect) shift ;; + noglob) glob=0; shift ;; + *) break ;; + esac + done + if ((glob)); then + PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $~==* + else + PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $==* + fi +} + +command -v _sudo >/dev/null 2>&1 +[[ $? -eq 0 ]] && compdef _sudo '_do_sudo' From 7f4d633f464eb8e2d7a8cc6ca8acb0fa05646132 Mon Sep 17 00:00:00 2001 From: Frederick Zhang Date: Sat, 21 Sep 2019 21:05:22 +1000 Subject: [PATCH 2/6] do_sudo: recursive alias expansion --- plugins/do_sudo/do_sudo.plugin.zsh | 40 ++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/plugins/do_sudo/do_sudo.plugin.zsh b/plugins/do_sudo/do_sudo.plugin.zsh index b59f3ac6a..73a17061e 100644 --- a/plugins/do_sudo/do_sudo.plugin.zsh +++ b/plugins/do_sudo/do_sudo.plugin.zsh @@ -5,21 +5,45 @@ else fi function _do_sudo() { - integer glob=1 - local -a run - run=( command sudo ) + [[ -z ${__do_sudo_glob+x} ]] && __do_sudo_glob=1 + [[ -z ${__do_sudo_expanded+x} ]] && declare -A __do_sudo_expanded + local -a args + local -a cmd_alias_arr + local cmd_alias while (($#)); do case "$1" in command|exec|-) shift; break ;; nocorrect) shift ;; - noglob) glob=0; shift ;; - *) break ;; + noglob) __do_sudo_glob=0; shift ;; + *) + cmd_alias="$(command -v 2>/dev/null -- "$1")" + if [[ "$?" -eq 0 ]]; then + if [[ "$cmd_alias" == 'alias'* ]] && [[ -z "$__do_sudo_expanded["$1"]" ]]; then + __do_sudo_expanded["$1"]=1 + IFS=' ' read -A cmd_alias_arr <<< "$(sed -e "s/[^=]*=//" -e "s/^'//" -e "s/'$//" <<< "$cmd_alias")" + args+=( "${cmd_alias_arr[@]}" ) + else + args+=( "$(sed "s/[^=]*=//" <<< "$(hash -v 2>/dev/null -- "$1")")" ) + fi + shift + break + else + args+=( $1 ) + shift + fi + ;; esac done - if ((glob)); then - PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $~==* + if [[ ${#cmd_alias_arr[@]} -gt 0 ]]; then + _do_sudo "${args[@]}" $==* else - PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $==* + if ((__do_sudo_glob)); then + PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" command sudo "${args[@]}" $~==* + else + PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" command sudo "${args[@]}" $==* + fi + unset __do_sudo_glob + unset __do_sudo_expanded fi } From 557234e352aed58726244fb786619f81b42c0e98 Mon Sep 17 00:00:00 2001 From: Frederick Zhang Date: Fri, 18 Oct 2019 21:41:39 +1100 Subject: [PATCH 3/6] do not resolve command to absolute path it breaks commands e.g. sudo -u http echo foobar as http is both a command (httpie) and a user/group (httpd) in my system --- plugins/do_sudo/do_sudo.plugin.zsh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plugins/do_sudo/do_sudo.plugin.zsh b/plugins/do_sudo/do_sudo.plugin.zsh index 73a17061e..85ca2d853 100644 --- a/plugins/do_sudo/do_sudo.plugin.zsh +++ b/plugins/do_sudo/do_sudo.plugin.zsh @@ -17,14 +17,10 @@ function _do_sudo() { noglob) __do_sudo_glob=0; shift ;; *) cmd_alias="$(command -v 2>/dev/null -- "$1")" - if [[ "$?" -eq 0 ]]; then - if [[ "$cmd_alias" == 'alias'* ]] && [[ -z "$__do_sudo_expanded["$1"]" ]]; then - __do_sudo_expanded["$1"]=1 - IFS=' ' read -A cmd_alias_arr <<< "$(sed -e "s/[^=]*=//" -e "s/^'//" -e "s/'$//" <<< "$cmd_alias")" - args+=( "${cmd_alias_arr[@]}" ) - else - args+=( "$(sed "s/[^=]*=//" <<< "$(hash -v 2>/dev/null -- "$1")")" ) - fi + if [[ "$?" -eq 0 ]] && [[ "$cmd_alias" == 'alias'* ]] && [[ -z "$__do_sudo_expanded["$1"]" ]]; then + __do_sudo_expanded["$1"]=1 + IFS=' ' read -A cmd_alias_arr <<< "$(sed -e "s/[^=]*=//" -e "s/^'//" -e "s/'$//" <<< "$cmd_alias")" + args+=( "${cmd_alias_arr[@]}" ) shift break else From 23f1c44ae2ba32b48b4386459058138836c8f98e Mon Sep 17 00:00:00 2001 From: Frederick Zhang Date: Mon, 21 Oct 2019 15:50:44 +1100 Subject: [PATCH 4/6] avoid conflict with 1-9 alises --- plugins/do_sudo/do_sudo.plugin.zsh | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/do_sudo/do_sudo.plugin.zsh b/plugins/do_sudo/do_sudo.plugin.zsh index 85ca2d853..8e28c1953 100644 --- a/plugins/do_sudo/do_sudo.plugin.zsh +++ b/plugins/do_sudo/do_sudo.plugin.zsh @@ -15,6 +15,7 @@ function _do_sudo() { command|exec|-) shift; break ;; nocorrect) shift ;; noglob) __do_sudo_glob=0; shift ;; + [1-9]) args+=( $1 ); shift ;; *) cmd_alias="$(command -v 2>/dev/null -- "$1")" if [[ "$?" -eq 0 ]] && [[ "$cmd_alias" == 'alias'* ]] && [[ -z "$__do_sudo_expanded["$1"]" ]]; then From aad3bb04a8c18f997e90f57c9d0eb74414bb52b2 Mon Sep 17 00:00:00 2001 From: Frederick Zhang Date: Wed, 23 Oct 2019 19:53:05 +1100 Subject: [PATCH 5/6] fix globbing --- plugins/do_sudo/do_sudo.plugin.zsh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/do_sudo/do_sudo.plugin.zsh b/plugins/do_sudo/do_sudo.plugin.zsh index 8e28c1953..8d1770e94 100644 --- a/plugins/do_sudo/do_sudo.plugin.zsh +++ b/plugins/do_sudo/do_sudo.plugin.zsh @@ -25,7 +25,11 @@ function _do_sudo() { shift break else - args+=( $1 ) + if ((__do_sudo_glob)); then + args+=( $~==1 ) + else + args+=( $==1 ) + fi shift fi ;; From 4de06d21e0eb9bd27f090a3863270833d3e64261 Mon Sep 17 00:00:00 2001 From: Frederick Zhang Date: Mon, 2 Mar 2020 18:21:33 +1100 Subject: [PATCH 6/6] preserve exit code --- plugins/do_sudo/do_sudo.plugin.zsh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/do_sudo/do_sudo.plugin.zsh b/plugins/do_sudo/do_sudo.plugin.zsh index 8d1770e94..f0bf8440f 100644 --- a/plugins/do_sudo/do_sudo.plugin.zsh +++ b/plugins/do_sudo/do_sudo.plugin.zsh @@ -10,6 +10,7 @@ function _do_sudo() { local -a args local -a cmd_alias_arr local cmd_alias + local return_value while (($#)); do case "$1" in command|exec|-) shift; break ;; @@ -43,8 +44,10 @@ function _do_sudo() { else PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" command sudo "${args[@]}" $==* fi + return_value=$? unset __do_sudo_glob unset __do_sudo_expanded + return $return_value fi }