AJ-Williams1
AJ-Williams1

Reputation: 126

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:

It works fine when I run that exact command with zsh, or if I run it in a script using zsh (i.e. 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)?

Upvotes: 2

Views: 136

Answers (1)

glenn jackman
glenn jackman

Reputation: 246744

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"

Upvotes: 6

Related Questions