]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bash-completion: correctly react to an unescaped unit name
authorFrantisek Sumsal <frantisek@sumsal.cz>
Thu, 25 Apr 2019 10:33:25 +0000 (12:33 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 30 May 2019 12:30:59 +0000 (14:30 +0200)
shell-completion/bash/journalctl
shell-completion/bash/systemctl.in

index d4aba59450bdcb4e0ecc50b984abf87d6805900b..35ff311bbd54b7d9ac506bd0fc6eacf9d956897e 100644 (file)
@@ -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)
index 8986f4537ab867d611eeee2547ebe24c63bbf842..1bda6f2b7c1739047346804459a09e572cba6c67 100644 (file)
@@ -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[*]}"