简体   繁体   中英

What part of this one-line script is specific to zsh?

I wrote a simple program called sarcasm that simply takes all its arguments, concatenates them, and converts the resulting string use 'aLtErNaTiNg CaPs'. I have written a simple one-line shell script that will let me use dmenu to enter text, run that text through this program, and copy the result to my clipboard. Here is what I have:

echo "dmenu -p 'Text: '" | sh | read var ; [[ -n "$var" ]] && echo -n $var | xargs sarcasm | xclip -selection clipboard

It is supposed to:

  • Prompt me for text using dmenu
  • If (and only if) I entered any text, run it through the sarcasm program and copy the result to my clipboard

It works fine when I run that exact command with zsh, or if I run it in a script using zsh (ie the shebang is #!/bin/zsh ), but when I run it with bash, it doesn't copy anything to my clipboard. What part of this is zsh-only, and what is the bash equivalent (if there is one)?

This part:

echo "dmenu -p 'Text: '" | sh | read var 
# ............................^^^^^^^^^^

In bash, each command in a pipeline is run in a separate subshell. Because the var variable is set in a subshell, the variable vanishes when the subshell exits.

To execute that in bash, redirect the output of a process substitution: this way, the read command runs in the current shell.

read -r var < <(dmenu -p 'Text: ')

I imagine that would work in zsh too.

There is another workaround: set the lastpipe setting and disable job control

$ echo foo | read var; declare -p var
bash: declare: var: not found

$ set +o monitor
$ shopt -s lastpipe
$ echo foo | read var; declare -p var
declare -- var="foo"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM