summaryrefslogtreecommitdiff
path: root/shell-completion
diff options
context:
space:
mode:
authorFrantisek Sumsal <frantisek@sumsal.cz>2019-04-25 12:33:25 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-05-30 14:30:59 +0200
commitcec82cb943d0fd23dd09309be62c6bcde6b47839 (patch)
treeddc20906b8cffb145a848d26ea107a3beb1549ef /shell-completion
parent665b0af8661e643614b12e923cb3fcf3f7bc0c07 (diff)
downloadsystemd-cec82cb943d0fd23dd09309be62c6bcde6b47839.tar.gz
bash-completion: correctly react to an unescaped unit name
Diffstat (limited to 'shell-completion')
-rw-r--r--shell-completion/bash/journalctl10
-rw-r--r--shell-completion/bash/systemctl.in28
2 files changed, 31 insertions, 7 deletions
diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl
index d4aba59450..35ff311bbd 100644
--- a/shell-completion/bash/journalctl
+++ b/shell-completion/bash/journalctl
@@ -87,6 +87,16 @@ _journalctl() {
;;
--unit|-u)
comps=$(journalctl -F '_SYSTEMD_UNIT' 2>/dev/null)
+ # Similarly to systemctl, we need to distinguish between
+ # escaped and unescaped names in order to be able to correctly
+ # complete them. In this particular case, if the name we're
+ # trying to complete is unescaped (i.e. foo\x2dbaz), escape
+ # it first, so the compgen below works as expected. For more
+ # information about these shenanigans see the systemctl
+ # completion file
+ if ! [[ $cur =~ '\\' ]]; then
+ cur="$(printf '%q' $cur)"
+ fi
compopt -o filenames
;;
--user-unit)
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index 8986f4537a..1bda6f2b7c 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -119,8 +119,7 @@ __get_machines() {
_systemctl () {
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
- local cur_orig=$cur
- local i verb comps mode
+ local i verb comps mode cur_orig
local -A OPTS=(
[STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
@@ -223,11 +222,26 @@ _systemctl () {
done
# When trying to match a unit name with certain special characters in its name (i.e
- # foo\x2dbar:01) they get escaped by bash along the way, thus causing any possible
- # match to fail. Let's unescape such characters in the verb we're trying to
- # autocomplete to avoid this, however, use the original verb (cur_orig)
- # during the final match (COMPREPLY)
- cur="$(echo $cur | xargs echo)"
+ # foo\x2dbar:01) they get (un)escaped by bash along the way, thus causing any possible
+ # match to fail.
+ # The following condition solves two cases:
+ # 1) We're trying to complete an already escaped unit name part,
+ # i.e foo\\x2dba. In this case we need to unescape the name, so it
+ # gets properly matched with the systemctl output (i.e. foo\x2dba).
+ # However, we need to keep the original escaped name as well for the
+ # final match, as the completion machinery does the unescaping
+ # automagically.
+ # 2) We're trying to complete an unescaped (literal) unit name part,
+ # i.e. foo\x2dba. That means we don't have to do the unescaping
+ # required for correct matching with systemctl's output, however,
+ # we need to escape the name for the final match, where the completion
+ # expects the string to be escaped.
+ cur_orig=$cur
+ if [[ $cur =~ '\\' ]]; then
+ cur="$(echo $cur | xargs echo)"
+ else
+ cur_orig="$(printf '%q' $cur)"
+ fi
if [[ -z $verb ]]; then
comps="${VERBS[*]}"