Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: sudo autocompletion
- X-seq: zsh-workers 45424
- From: dana <dana@xxxxxxx>
- To: Oliver Kiddle <okiddle@xxxxxxxxxxx>
- Subject: Re: sudo autocompletion
- Date: Wed, 12 Feb 2020 19:21:08 -0600
- Cc: Zsh hackers list <zsh-workers@xxxxxxx>, Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
- In-reply-to: <17405-1581415941.062275@CNCV.ghXS.ifR->
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <912d22db-8a8f-90f2-6738-f9f395994dcb@gmail.com> <CAN=4vMqvzUTZ7bBLcbTzi-pKAVEP1xDbq=f5pLAxmffxUjTszQ@mail.gmail.com> <1770be62-54d8-70a6-8b05-cfc98faa9b9f@gmail.com> <20200210030219.527a3ccf@tarpaulin.shahaf.local2> <ADE72275-1311-44BE-9B1D-5E617E3D9F94@gmail.com> <D0BDD1BB-192E-4D50-A0D2-0BB54388B9B9@dana.is> <20200210192033.1bae83dc@tarpaulin.shahaf.local2> <17405-1581415941.062275@CNCV.ghXS.ifR->
On 11 Feb 2020, at 04:12, Oliver Kiddle <okiddle@xxxxxxxxxxx> wrote:
> We already set _comp_priv_prefix, _command_names could detect that
> and adjust a local $path if it is set.
I made some related changes here that i can break out into separate patches if
it makes it easier. But this is the summary:
* Have _command_names append the sbin variants if command-path is not set but
_comp_priv_prefix is
* Add some indirection around setting _c_p_p in _doas, _pfexec, and _sudo — i
think the purpose of delaying the assignment is to make sure that opt_args
has been populated
* Have _doas call `_command_names -e` separately like _sudo and _pfexec do (it
can't complete shell commands)
* Have _pfexec use $words[1] for _c_p_p (the $cmd indirection is there because
$words is changed by the *:: spec)
* Fix broken opt_args references in _doas and _pfexec — they need the (I)
flag, and using argument sets in _doas makes it ugly to extract options, so
i have it just using exclusion lists now instead
* Change -P to -P+ in _pfexec
Does this make sense?
PS: This does not fix `su -c` — _su doesn't set _c_p_p, presumably because it
always prompts for a password. But since _c_p_p is passed directly to eval, we
*could* make it set _c_p_p=( '' ), which would trick _command_names into doing
the right thing. Is that too silly?
dana
diff --git a/Completion/Solaris/Command/_pfexec b/Completion/Solaris/Command/_pfexec
index 2519c3cdc..fc2bca835 100644
--- a/Completion/Solaris/Command/_pfexec
+++ b/Completion/Solaris/Command/_pfexec
@@ -22,11 +22,15 @@ _privset() {
}
_pfexec() {
+ local cmd cpp
local -a _comp_priv_prefix
+ local -A opt_args
+ cmd="$words[1]"
+ cpp='_comp_priv_prefix=( $cmd ${(kv)opt_args[(I)-P]} )'
_arguments \
- '-P[privileges to acquire]:privspec:_privset' \
- '(-):command name: _command_names -e' \
- '*::arguments:{ _comp_priv_prefix=( pfexec ${(kv)opt_args[-P]} ) ; _normal }'
+ '-P+[privileges to acquire]:privspec:_privset' \
+ "(-): :{ $cpp; _command_names -e }" \
+ "*:: :{ $cpp; _normal }"
}
_pfexec "$@"
diff --git a/Completion/Unix/Command/_doas b/Completion/Unix/Command/_doas
index 94395557c..2494f1c5f 100644
--- a/Completion/Unix/Command/_doas
+++ b/Completion/Unix/Command/_doas
@@ -1,7 +1,8 @@
#compdef doas
-local environ e cmd
+local environ e cmd cpp
local -a _comp_priv_prefix
+local -A opt_args
zstyle -a ":completion:${curcontext}:" environ environ
@@ -10,13 +11,13 @@ do local -x "$e"
done
cmd="$words[1]"
+cpp='_comp_priv_prefix=( $cmd -n ${(kv)opt_args[(I)-u]} )'
_arguments -s -S -A '-*' : \
- - optL \
- '-L[clear any persisted authorizations]' \
- - default \
- '-a+[specify authentication style]:authentication style' \
- '(-n -s)-C+[check config file and report on command matching]:config:_files' \
- '(-C)-n[non-interactive: fail rather than prompt for a password]' \
- '(-C *)-s[run a shell]' \
- '-u+[run command as specified user]:user:_users' \
- '*::arguments:{ _comp_priv_prefix=( $cmd -n ${(kv)opt_args[-u]} ) ; _normal }'
+ '(: * -)-L[clear any persisted authorizations]' \
+ '(-L)-a+[specify authentication style]:authentication style' \
+ '(-L -n -s)-C+[check config file and report on command matching]:config:_files' \
+ '(-C -L)-n[non-interactive: fail rather than prompt for a password]' \
+ '(-C -L *)-s[run a shell]' \
+ '(-L)-u+[run command as specified user]:user:_users' \
+ "(-)1: :{ $cpp; _command_names -e }" \
+ "*:: :{ $cpp; _normal }"
diff --git a/Completion/Unix/Command/_sudo b/Completion/Unix/Command/_sudo
index 41e32cbae..e3d12d72f 100644
--- a/Completion/Unix/Command/_sudo
+++ b/Completion/Unix/Command/_sudo
@@ -2,9 +2,9 @@
setopt localoptions extended_glob
-local environ e cmd
-local -a args
-local -a _comp_priv_prefix
+local environ e cmd cpp
+local -a args _comp_priv_prefix
+local -A opt_args
zstyle -a ":completion:${curcontext}:" environ environ
@@ -42,6 +42,10 @@ if [[ $service = sudoedit ]] || (( $words[(i)-e] < $words[(i)^(*sudo|-[^-]*)] ))
args=( -A "-*" $args '!(-V --version -h --help)-e' '*:file:_files' )
else
cmd="$words[1]"
+ cpp='_comp_priv_prefix=(
+ $cmd -n
+ ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]}
+ )'
args+=(
'(-e --edit 1 *)'{-e,--edit}'[edit files instead of running a command]' \
'(-s --shell)'{-s,--shell}'[run shell as the target user; a command may also be specified]' \
@@ -51,8 +55,8 @@ else
'(-E -i --login -s --shell -e --edit)--preserve-env=-[preserve user environment when running command]::environment variable:_sequence _parameters -g "*export*"' \
'(-H --set-home -i --login -s --shell -e --edit)'{-H,--set-home}"[set HOME variable to target user's home dir]" \
'(-P --preserve-groups -i -login -s --shell -e --edit)'{-P,--preserve-groups}"[preserve group vector instead of setting to target's]" \
- '(-)1:command: _command_names -e'
- '*::arguments:{ _comp_priv_prefix=( $cmd -n ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]} ) ; _normal }'
+ "(-)1: :{ $cpp; _command_names -e }"
+ "*:: :{ $cpp; _normal }"
)
fi
diff --git a/Completion/Zsh/Type/_command_names b/Completion/Zsh/Type/_command_names
index cd630b7a4..b1c35f013 100644
--- a/Completion/Zsh/Type/_command_names
+++ b/Completion/Zsh/Type/_command_names
@@ -41,11 +41,24 @@ fi
args=( "$@" )
local -a cmdpath
-if zstyle -a ":completion:${curcontext}" command-path cmdpath &&
- [[ $#cmdpath -gt 0 ]]
-then
+
+zstyle -a ":completion:${curcontext}" command-path cmdpath
+
+# Using the current PATH doesn't necessarily make sense when completing commands
+# to tools like sudo, which might set a different one. A common issue is that
+# /**/sbin appear in the PATH used by the tool, but not in the one used by the
+# unprivileged user who calls it. To do the right thing in the most common
+# cases, we'll simply ensure that the sbin variants always appear here when not
+# otherwise overridden (bash-completion's _sudo does something similar)
+if (( ! $#cmdpath && $#_comp_priv_prefix )); then
+ cmdpath=( $path ${path/%\/bin//sbin} )
+ cmdpath=( ${(u)^cmdpath}(/-N) )
+fi
+
+if (( $#cmdpath )); then
local -a +h path
local -A +h commands
path=( $cmdpath )
fi
+
_alternative -O args "$defs[@]"
Messages sorted by:
Reverse Date,
Date,
Thread,
Author