mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 10:19:50 +00:00
Merge pull request #31144 from ohmystack/fix/zsh-completion
Automatic merge from submit-queue Fix named pipe in kubectl zsh completion This PR fixes #28049 Though my zsh version > 5.0, I still got the problem. So, I think we need this fix. --- ### Env ``` OS: Ubuntu 14.04 $ zsh --version zsh 5.0.2 (x86_64-pc-linux-gnu) ``` ### A simple DEMO to show the root cause In zsh and bash, a multi-line named pipe, who is wrapped by parenthesis, is possible to mismatch the "right parenthesis", even that parenthesis is in a here-document. The following script was going to use `sed` to print the text in the 'BASH_COMPLETION_EOF' here-document. > * I made the `sed` simpler. As you can see, `sed` actually does nothing here. It just prints what it gets from `<<`). In real [`pkg/kubectl/cmd/completion.go`](https://github.com/kubernetes/kubernetes/blob/v1.3.5/pkg/kubectl/cmd/completion.go#L246-L258), `sed` will do some text replacement, changing bash functions to zsh functions. But that is not the point of the problem. > * I use `cat <(...)` to replace the `source <(...)`. > In this way, we can see how named pipe works. run-bad.zsh: ```bash #!/usr/bin/zsh cat <(sed -e 's/foo/bar/g' <<'BASH_COMPLETION_EOF' aaa='aaa' case aaa in 'aaa') # <- This ')' is in a here-document, but it is handled by named pipe by mistake. echo 'yes' ;; esac BASH_COMPLETION_EOF ) ``` > Output: > ``` > ./run-bad.zsh > aaa='aaa' > case aaa in > 'aaa'yes <- You can see the here-document `echo yes` has been executed!!! > ./run-bad.zsh:8: parse error near `;;' > ``` The named pipe `<(sed ...` "eats" the `)`, which should belong to `case aaa in 'aaa')`. So that the named pipe ends earlier than expectation. The left zsh code is broken, it fails. ### Here's the fix Move the code into a function, and use an inline named pipe. run.zsh: ```bash #!/usr/bin/zsh print_sed_result() { sed -e 's/foo/bar/g' <<'BASH_COMPLETION_EOF' aaa='aaa' case aaa in 'aaa') echo 'yes' ;; esac BASH_COMPLETION_EOF } cat <(print_sed_result) # <- Use an inline named pipe ``` > Output: > ``` > ./run.zsh > stack@docker-dev01 > aaa='aaa' > case aaa in > 'aaa') > echo 'yes' > ;; > esac > ``` Now, the here-document and named pipe work correctly.
This commit is contained in:
commit
ae3b956c65
@ -245,7 +245,8 @@ if sed --help 2>&1 | grep -q GNU; then
|
|||||||
RWORD='\>'
|
RWORD='\>'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
__kubectl_bash_source <(sed \
|
__kubectl_convert_bash_to_zsh() {
|
||||||
|
sed \
|
||||||
-e 's/declare -F/whence -w/' \
|
-e 's/declare -F/whence -w/' \
|
||||||
-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
|
-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
|
||||||
-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
|
-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
|
||||||
@ -267,7 +268,9 @@ __kubectl_bash_source <(sed \
|
|||||||
|
|
||||||
zsh_tail := `
|
zsh_tail := `
|
||||||
BASH_COMPLETION_EOF
|
BASH_COMPLETION_EOF
|
||||||
)
|
}
|
||||||
|
|
||||||
|
__kubectl_bash_source <(__kubectl_convert_bash_to_zsh)
|
||||||
`
|
`
|
||||||
out.Write([]byte(zsh_tail))
|
out.Write([]byte(zsh_tail))
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user