zsh-users
 help / color / mirror / code / Atom feed
* Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
@ 2004-08-16  1:04 Aaron Davies
  2004-08-16  2:42 ` Bart Schaefer
  2004-08-16  3:03 ` Philippe Troin
  0 siblings, 2 replies; 12+ messages in thread
From: Aaron Davies @ 2004-08-16  1:04 UTC (permalink / raw)
  To: zsh-users

How do I do return-value error handling in the middle of a pipeline? 
I'd ideally like to keep this to as basic a shell level as possible, 
plain (Bourne) sh-compatible if it can be done, though a bash or zsh 
solution will be fine if not. I'm tring to write a simple script that 
will apply a command to all processes matching a name--sort of a 
generalized "killall". At the moment, it looks like this:

#!/bin/sh

name=$1
shift

ps aux | grep $name | grep -v grep | grep -v $0 | awk '{ print $2 }' | 
xargs $@

and it works fine, and I'd like to keep it at that level of simplicity. 
The only thing is, I'd like to make it stop and return 1 if there are 
no matching processes. (At the moment, it calls the command with an 
empty argument list.) The intuitive thing to do seems to be

ps aux | grep $name | grep -v grep | ( grep -v $0 || exit 1 ) | awk '{ 
print $2 }' | xargs $@

but that doesn't work. Any ideas? (I could, of course, simply cache the 
last grep's results in a tmpfile, test its length, and proceed 
accordingly, but that doesn't seem quite as elegant.
-- 
Aaron Davies
agdavi01@louisville.edu


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16  1:04 Slightly OT: Error-Handling in a Pipeline, preferably non-zsh Aaron Davies
@ 2004-08-16  2:42 ` Bart Schaefer
  2004-08-16  3:33   ` Aaron Davies
  2004-08-16  3:03 ` Philippe Troin
  1 sibling, 1 reply; 12+ messages in thread
From: Bart Schaefer @ 2004-08-16  2:42 UTC (permalink / raw)
  To: zsh-users

On Sun, 15 Aug 2004, Aaron Davies wrote:

> How do I do return-value error handling in the middle of a pipeline?

The trouble is that you're not asking for return-value error handling,
you're asking for conditional execution.  That is, you want a pipeline
that acts like an && conjunction.  This just can't be; in order to set up 
all the stdout-to-stdin connections between the processes in the pipeline,
the controlling shell must start them up without knowing whether any one
of them is (or isn't) actually going to produce (or consume) any output.

The closest you could get would be to use a named pipe:

  mkfifo psgrep
  { ps aux | grep $name | grep -v grep | grep -v $0; } > psgrep &&
  { awk '{ print $2 }' | xargs $@; } < psgrep
  rm psgrep

However, that's subject to deadlock if the the first pipeline produces 
more output before it exits than can be buffered in the fifo, and except 
for the mkfifo it looks exactly the same as the temp file solution you 
already suggested.

There is no reliable way to do this without capturing the first part of 
the output somewhere.  Instead of using a temp file, you could capture in 
a variable:

  psgrep="`ps aux | grep $name | grep -v grep | grep -v $0`"
  [ -n "$psgrep" ] && { echo "$psgrep" | awk '{ print $2 }' | xargs $@; }

Or you could skip the awk and xargs entirely and use a while loop:

  ps aux | grep $name | grep -v grep | grep -v $0 |
  while read user pid remainder
  do
    $@ $pid
  done

As a final note, you probably want "$@" in double quotes.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16  1:04 Slightly OT: Error-Handling in a Pipeline, preferably non-zsh Aaron Davies
  2004-08-16  2:42 ` Bart Schaefer
@ 2004-08-16  3:03 ` Philippe Troin
  2004-08-16  3:30   ` Aaron Davies
  1 sibling, 1 reply; 12+ messages in thread
From: Philippe Troin @ 2004-08-16  3:03 UTC (permalink / raw)
  To: Aaron Davies; +Cc: zsh-users

Aaron Davies <agdavi01@louisville.edu> writes:

> How do I do return-value error handling in the middle of a pipeline?
> I'd ideally like to keep this to as basic a shell level as possible,
> plain (Bourne) sh-compatible if it can be done, though a bash or zsh
> solution will be fine if not. I'm tring to write a simple script that
> will apply a command to all processes matching a name--sort of a
> generalized "killall". At the moment, it looks like this:
> 
> #!/bin/sh
> 
> name=$1
> shift
> 
> ps aux | grep $name | grep -v grep | grep -v $0 | awk '{ print $2 }' |
> xargs $@
> 
> and it works fine, and I'd like to keep it at that level of
> simplicity. The only thing is, I'd like to make it stop and return 1
> if there are no matching processes. (At the moment, it calls the
> command with an empty argument list.) The intuitive thing to do seems
> to be
> 
> ps aux | grep $name | grep -v grep | ( grep -v $0 || exit 1 ) | awk '{
> print $2 }' | xargs $@

Use your first idiom and check $pipestatus[4].

Phil.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16  3:03 ` Philippe Troin
@ 2004-08-16  3:30   ` Aaron Davies
  2004-08-16  7:51     ` Bart Schaefer
  0 siblings, 1 reply; 12+ messages in thread
From: Aaron Davies @ 2004-08-16  3:30 UTC (permalink / raw)
  To: zsh-users

On Sunday, August 15, 2004, at 11:03 PM, Philippe Troin wrote:

> Aaron Davies <agdavi01@louisville.edu> writes:
>
>> How do I do return-value error handling in the middle of a pipeline?
>> I'd ideally like to keep this to as basic a shell level as possible,
>> plain (Bourne) sh-compatible if it can be done, though a bash or zsh
>> solution will be fine if not. I'm tring to write a simple script that
>> will apply a command to all processes matching a name--sort of a
>> generalized "killall". At the moment, it looks like this:
>>
>> #!/bin/sh
>>
>> name=$1
>> shift
>>
>> ps aux | grep $name | grep -v grep | grep -v $0 | awk '{ print $2 }' |
>> xargs $@
>>
>> and it works fine, and I'd like to keep it at that level of
>> simplicity. The only thing is, I'd like to make it stop and return 1
>> if there are no matching processes. (At the moment, it calls the
>> command with an empty argument list.) The intuitive thing to do seems
>> to be
>>
>> ps aux | grep $name | grep -v grep | ( grep -v $0 || exit 1 ) | awk '{
>> print $2 }' | xargs $@
>
> Use your first idiom and check $pipestatus[4].

Thanks, that seems to solve it (though it's [3], not [4]). I've 
combined that with xargs's "-r" option, which aborts if there are no 
arguments passed, to produce the following as the final script:

#!/bin/sh

name=$1
shift

ps aux | grep $name | grep -v grep | grep -v $0 | awk '{ print $2 }' | 
xargs -r "$@"
test ${PIPESTATUS[3]} -eq 0 && exit || exit 1
-- 
     __                      __
    /  )                    /  )
   /--/ __. .__  ______    /  / __. , __o  _  _
  /  (_(_/|_/ (_(_) / (_  (__/_(_/|_\/ <__</_/_)_


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16  2:42 ` Bart Schaefer
@ 2004-08-16  3:33   ` Aaron Davies
  2004-08-16  7:41     ` Bart Schaefer
  0 siblings, 1 reply; 12+ messages in thread
From: Aaron Davies @ 2004-08-16  3:33 UTC (permalink / raw)
  To: zsh-users

On Sunday, August 15, 2004, at 10:42 PM, Bart Schaefer wrote:

> On Sun, 15 Aug 2004, Aaron Davies wrote:
>
>> How do I do return-value error handling in the middle of a pipeline?
>
> Or you could skip the awk and xargs entirely and use a while loop:
>
>   ps aux | grep $name | grep -v grep | grep -v $0 |
>   while read user pid remainder
>   do
>     $@ $pid
>   done

What do you think of the solution I replied to Phillipe with, using 
xargs with "-r" and just checking the pipestatus to determine exit?

> As a final note, you probably want "$@" in double quotes.

Really? I used it with multi-word commands (like "kill -9") with no 
problems.
-- 
     __                      __
    /  )                    /  )
   /--/ __. .__  ______    /  / __. , __o  _  _
  /  (_(_/|_/ (_(_) / (_  (__/_(_/|_\/ <__</_/_)_


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16  3:33   ` Aaron Davies
@ 2004-08-16  7:41     ` Bart Schaefer
  2004-08-16 12:40       ` Aaron Davies
  0 siblings, 1 reply; 12+ messages in thread
From: Bart Schaefer @ 2004-08-16  7:41 UTC (permalink / raw)
  To: zsh-users

On Sun, 15 Aug 2004, Aaron Davies wrote:

> >   ps aux | grep $name | grep -v grep | grep -v $0 |
> 
> What do you think of the solution I replied to Phillipe with, using 
> xargs with "-r" and just checking the pipestatus to determine exit?

It should work fine.  It just isn't what (I thought) you were asking for 
-- it still runs both awk and xargs even when the greps find nothing.

> > As a final note, you probably want "$@" in double quotes.
> 
> Really? I used it with multi-word commands (like "kill -9") with no 
> problems.

What happens when one of the arguments of the command is a quoted word 
containing spaces?  E.g. supposing your "generalized killall" is named
"runcommandonpidof" (since you've never told us what it _is_ called), try

  sleep 30 &
  runcommandonpidof sleep print -l "this should be on one line"

(and try it in a non-zsh shell, where word splitting applies; no cheating 
by letting zsh preserve the quoting for you, you asked for portability).


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16  3:30   ` Aaron Davies
@ 2004-08-16  7:51     ` Bart Schaefer
  2004-08-16 12:41       ` Aaron Davies
  0 siblings, 1 reply; 12+ messages in thread
From: Bart Schaefer @ 2004-08-16  7:51 UTC (permalink / raw)
  To: zsh-users

On Sun, 15 Aug 2004, Aaron Davies wrote:

> On Sunday, August 15, 2004, at 11:03 PM, Philippe Troin wrote:
> 
> > Use your first idiom and check $pipestatus[4].
> 
> Thanks, that seems to solve it (though it's [3], not [4]).

If you have the KSH_ARRAYS option set, it's best to say so when asking for
help on this list, or you're going to see a lot of this kind of "mistake."


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16  7:41     ` Bart Schaefer
@ 2004-08-16 12:40       ` Aaron Davies
  2004-08-16 14:53         ` DervishD
  0 siblings, 1 reply; 12+ messages in thread
From: Aaron Davies @ 2004-08-16 12:40 UTC (permalink / raw)
  To: zsh-users

On Monday, August 16, 2004, at 03:41 AM, Bart Schaefer wrote:

> On Sun, 15 Aug 2004, Aaron Davies wrote:
>
>>> As a final note, you probably want "$@" in double quotes.
>>
>> Really? I used it with multi-word commands (like "kill -9") with no 
>> problems.
>
> What happens when one of the arguments of the command is a quoted word 
> containing spaces?  E.g. supposing your "generalized killall" is named 
> "runcommandonpidof" (since you've never told us what it _is_ called), 
> try

It's called "toall".

>   sleep 30 &
>   runcommandonpidof sleep print -l "this should be on one line"
>
> (and try it in a non-zsh shell, where word splitting applies; no 
> cheating by letting zsh preserve the quoting for you, you asked for 
> portability).

What is "print"? There doesn't seem to be an executable of that name on 
my (OS X 10.3) box, and printf doesn't have a "-l" option. I tried 
something similar with echo, and saw no difference.

toall sleep echo "this is one line"

produces

this is one line 19980

whether or not $@ is in quotes. (I was invoking the script from sh, 
which I think on this box is actually bash running in sh-mode.)
-- 
     __                      __
    /  )                    /  )
   /--/ __. .__  ______    /  / __. , __o  _  _
  /  (_(_/|_/ (_(_) / (_  (__/_(_/|_\/ <__</_/_)_


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16  7:51     ` Bart Schaefer
@ 2004-08-16 12:41       ` Aaron Davies
  2004-08-16 16:08         ` Dan Nelson
  0 siblings, 1 reply; 12+ messages in thread
From: Aaron Davies @ 2004-08-16 12:41 UTC (permalink / raw)
  To: zsh-users

On Monday, August 16, 2004, at 03:51 AM, Bart Schaefer wrote:

> On Sun, 15 Aug 2004, Aaron Davies wrote:
>
>> On Sunday, August 15, 2004, at 11:03 PM, Philippe Troin wrote:
>>
>>> Use your first idiom and check $pipestatus[4].
>>
>> Thanks, that seems to solve it (though it's [3], not [4]).
>
> If you have the KSH_ARRAYS option set, it's best to say so when asking 
> for
> help on this list, or you're going to see a lot of this kind of 
> "mistake."

I'm running this under Bourne sh, as I mentioned in my original 
request. (Well, technically, I think on this box it's bash, running in 
sh emulation mode.) I assume this is the default array indexing mode 
for sh?
-- 
     __                      __
    /  )                    /  )
   /--/ __. .__  ______    /  / __. , __o  _  _
  /  (_(_/|_/ (_(_) / (_  (__/_(_/|_\/ <__</_/_)_


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16 12:40       ` Aaron Davies
@ 2004-08-16 14:53         ` DervishD
  2004-08-17  3:06           ` Bart Schaefer
  0 siblings, 1 reply; 12+ messages in thread
From: DervishD @ 2004-08-16 14:53 UTC (permalink / raw)
  To: Aaron Davies; +Cc: zsh-users

    Hi Aaron :)

 * Aaron Davies <agdavi01@louisville.edu> dixit:
> What is "print"? There doesn't seem to be an executable of that name on 
> my (OS X 10.3) box, and printf doesn't have a "-l" option. I tried 
> something similar with echo, and saw no difference.

    'print' is a zsh builtin.

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16 12:41       ` Aaron Davies
@ 2004-08-16 16:08         ` Dan Nelson
  0 siblings, 0 replies; 12+ messages in thread
From: Dan Nelson @ 2004-08-16 16:08 UTC (permalink / raw)
  To: Aaron Davies; +Cc: zsh-users

In the last episode (Aug 16), Aaron Davies said:
> On Monday, August 16, 2004, at 03:51 AM, Bart Schaefer wrote:
> >On Sun, 15 Aug 2004, Aaron Davies wrote:
> >>On Sunday, August 15, 2004, at 11:03 PM, Philippe Troin wrote:
> >>
> >>>Use your first idiom and check $pipestatus[4].
> >>
> >>Thanks, that seems to solve it (though it's [3], not [4]).
> >
> >If you have the KSH_ARRAYS option set, it's best to say so when
> >asking for help on this list, or you're going to see a lot of this
> >kind of "mistake."
> 
> I'm running this under Bourne sh, as I mentioned in my original
> request. (Well, technically, I think on this box it's bash, running
> in sh emulation mode.) I assume this is the default array indexing
> mode for sh?

Bourne shell doesn't have arrays or $pipestatus, so if you really want
/bin/sh compatibility, you can't use either.  You'll probably have to
split your pipe at the place you want to check the resultcode, and use
a temp variable to store your intermediate output.

-- 
	Dan Nelson
	dnelson@allantgroup.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Slightly OT: Error-Handling in a Pipeline, preferably non-zsh
  2004-08-16 14:53         ` DervishD
@ 2004-08-17  3:06           ` Bart Schaefer
  0 siblings, 0 replies; 12+ messages in thread
From: Bart Schaefer @ 2004-08-17  3:06 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1275 bytes --]

Sigh.  Someday maybe I'll decide not to answer email in the middle of the 
night when I've been taking decongestants.

On Mon, 16 Aug 2004, Aaron Davies wrote:

> On Monday, August 16, 2004, at 03:41 AM, Bart Schaefer wrote:
> 
> > What happens when one of the arguments of the command is a quoted word
> > containing spaces?
[...]
> >   sleep 30 &
> >   runcommandonpidof sleep print -l "this should be on one line"
> > 
> > (and try it in a non-zsh shell, where word splitting applies; no 
> > cheating by letting zsh preserve the quoting for you, you asked for 
> > portability).
> 
> What is "print"?

As has been pointed out by Raúl, I've been telling you to avoid zsh while 
giving an example that uses a zsh builtin.

> toall sleep echo "this is one line"
> 
> produces
> 
> this is one line 19980
> 
> whether or not $@ is in quotes.

Try this one:

	toall sleep echo "this has          ten spaces"

With $@, you should get

	this has ten spaces 19980

Whereas "$@" should give

	this has          ten spaces 19980

On Mon, 16 Aug 2004, Aaron Davies wrote:

> I'm running this under Bourne sh, as I mentioned in my original request.

And I should have remembered, as Dan Nelson mentioned, that $pipestatus is
only available in bash and zsh and therefore not portable.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2004-08-17  3:08 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-16  1:04 Slightly OT: Error-Handling in a Pipeline, preferably non-zsh Aaron Davies
2004-08-16  2:42 ` Bart Schaefer
2004-08-16  3:33   ` Aaron Davies
2004-08-16  7:41     ` Bart Schaefer
2004-08-16 12:40       ` Aaron Davies
2004-08-16 14:53         ` DervishD
2004-08-17  3:06           ` Bart Schaefer
2004-08-16  3:03 ` Philippe Troin
2004-08-16  3:30   ` Aaron Davies
2004-08-16  7:51     ` Bart Schaefer
2004-08-16 12:41       ` Aaron Davies
2004-08-16 16:08         ` Dan Nelson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).