2

I am executing:

Command1 | tee >(grep sth) || Command2 

I want Command2 to be executed based on the exit status of grep, while in the current configuration it is being executed based on the result of tee.

As far as I know pipefail and pipestatus are not working here (please correct me if I am wrong).

Modification to the Origian question based on Alexej Answer

I also tried Command1 | tee >(grep sth || Command2), which works for my original question, but as I am trying to set the status of my test in the subshell; ex, Command 1 | tee>(grep sth || Result="PASSED") and later have access to the Result in other chunks of my code. So I still have problem.

Thanks

codeforester
  • 39,467
  • 16
  • 112
  • 140
Aman
  • 1,157
  • 7
  • 13
  • does `command1 | tee | grep sth` not work? Is there any reason why you need to use a subshell? – Alexej Magura Apr 16 '14 at 16:56
  • I need to log the output of "Command1" and also the output of "grep" (some device testing requirement). By using pipe, I cannot record the output of the "Command1". An alternative is to execute Command1, log the output, then execute it for second time and pipe it to grep, which is ugly :). "command1 | tee | grep sth" redirect the stdout to grep. Here is my 1st question http://stackoverflow.com/questions/23066559/simultaneous-pipe-to-grep-and-redirect-to-stdout/23066748?noredirect=1#23066748 that leaded me to use subshell and .... – Aman Apr 16 '14 at 17:05
  • okay, so you're saying that `if (command1 | tee | grep sth &> /dev/null); then command2; fi` right? – Alexej Magura Apr 16 '14 at 17:18

1 Answers1

2

Change your script to:

Command1 | tee >(grep sth || Command2)

to achieve the desired result.

A word about Subshells

>(....) is a subshell. Anything and everything that you do within that subshell (except for the exit status of said subshell) is completely isolated from the outside world: (a=1); echo $a will never echo the number 1, because a only has meaning within the subshell where it is defined.

I don't entirely understand why, but when you do redirection to a subshell, it seems to invert the exit status of that subshell, so that a failure will return true and a success will return false.

echo 'a' >(grep 'b') && echo false
# false
(exit 1) || echo false
# false

So if my first suggestion isn't working out for you, then try re-writing your script thusly:

Command1 | tee >(grep sth) && Command2

An example

a=1 # `a` now equals `1`
# if I run `exit`, $a will go out of scope and the terminal I'm in might exit
(exit) # $a doesn't go out of scope because `exit` was run from within a subshell.
echo $a # $a still equals `1`

Where you can go to learn more about subshells

Set a parent shell's variable from a subshell
Pass variable from a child to parent in KSH
Variables value gets lost in subshell
http://www.tldp.org/LDP/abs/html/subshells.html
http://mywiki.wooledge.org/SubShell
http://wiki.bash-hackers.org/syntax/expansion/proc_subst

Community
  • 1
  • 1
Alexej Magura
  • 4,833
  • 3
  • 26
  • 40
  • I still have some problem: Coomand1 | tee >(grep sth || Command2) works perfectly, but Coomand1 | tee >(grep sth || var1=sth) does not work. Is there any reason that I cannot assign an argument in this configuration. – Aman Apr 14 '14 at 21:29
  • what do you mean by "I cannot assign an argument in this config..."? Do you mean that it runs just fine, but you can't access the variable? – Alexej Magura Apr 14 '14 at 22:34
  • Assume that I assigned {var1=2}, then later I am running {Command1 | tee >(grep sth || var1=3)} (Command | tee >(grep sth) exit status is 0). Later, I check for the $var1 which is still 2, while it should be 3. – Aman Apr 15 '14 at 14:32
  • @Aman I've updated my answer to address the variable issue that you're encountering. – Alexej Magura Apr 15 '14 at 17:41
  • Thx, I updated the question as well (based on your answer) as I am still struggling with it. – Aman Apr 16 '14 at 15:05