LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 07-06-2006, 05:44 AM   #1
humbletech99
Member
 
Registered: Jun 2005
Posts: 374

Rep: Reputation: 30
Bash command exit status


When I do
Code:
somecommand | head -n 2
$? is always the exit status of the "head" command rather than that of "somecommand"

Is there a way to do this and to test the exit status of "somecommand" rather than "head" (which will always be success even if somecommand fails) ?
 
Old 07-06-2006, 05:55 AM   #2
raskin
Senior Member
 
Registered: Sep 2005
Location: Russia
Distribution: NixOS (http://nixos.org)
Posts: 1,891

Rep: Reputation: 68
I guess it's rather hard: really, somecommand will very often get sigpipe after head exits. So its exit status is mangled. You can create a temporary file with mktemp, redirect somecommand to it, remember exit status, show two first lines of a file to user and then remove the file.
 
Old 07-06-2006, 06:01 AM   #3
humbletech99
Member
 
Registered: Jun 2005
Posts: 374

Original Poster
Rep: Reputation: 30
that's what I've ended up doing but it is not elegent and if /tmp is full the script won't work as expected...
 
Old 07-06-2006, 06:02 AM   #4
druuna
LQ Veteran
 
Registered: Sep 2003
Location: the Netherlands
Distribution: lfs, debian, rhel
Posts: 7,514
Blog Entries: 1

Rep: Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140
Hi,

Like raskin said, this is not easy to solve without some extra work. Maybe this will help:

somecommand 1>/dev/null 2>&1 && somecommand | head -n 2

If the first part (somecommand 1>/dev/null 2>&1) fails, the rest (somecommand | head -n 2) is not executed and accordingly the exit status is 1. If the first part works, the second part is executed (with always has exit status 0, as you stated).

BTW: The && stands for AND.

Hope this helps.
 
Old 07-06-2006, 09:10 AM   #5
spirit receiver
Member
 
Registered: May 2006
Location: Frankfurt, Germany
Distribution: SUSE 10.2
Posts: 424

Rep: Reputation: 31
This might be of interest (from man bash):
Quote:
The return status of a pipeline is the exit status of the last command, unless the pipefail option is enabled. If pipefail is enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.
 
Old 07-06-2006, 09:49 AM   #6
druuna
LQ Veteran
 
Registered: Sep 2003
Location: the Netherlands
Distribution: lfs, debian, rhel
Posts: 7,514
Blog Entries: 1

Rep: Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140
Hi again,

Nice, did not know that.

But: The pipefail option depends on the bash version you are using. My version uses the ! to toggle the way the exit status is handled inside a pipe, pipefail is not recognized or mentioned in the manpage.

This:

! somecommand | head -n 2

Does the trick on my box.

$ bash --version
GNU bash, version 2.05b.0(1)-release (i686-pc-linux-gnu)
Copyright (C) 2002 Free Software Foundation, Inc.
 
Old 07-06-2006, 09:54 AM   #7
humbletech99
Member
 
Registered: Jun 2005
Posts: 374

Original Poster
Rep: Reputation: 30
thank you guys, that was very helpful!

druuna: your suggestion does work and is quite clever, but unfortunately the head command only filters the second command after the && so I can't catch and limit the output.

spirit receiver: I read the man bash again and found the references for pipefail, then at the beginning of the script I did "set -o pipefail" and but later in the script it seems to always return status of 141 for the pipe command regarless of whether it works or not!
 
Old 07-06-2006, 10:08 AM   #8
spirit receiver
Member
 
Registered: May 2006
Location: Frankfurt, Germany
Distribution: SUSE 10.2
Posts: 424

Rep: Reputation: 31
Works fine here. Maybe you should post the code that causes your problems.

Edit: As an alternative, you could use process substitution:
Code:
cat file-does-not-exist > >(head -2); echo $?
cat: file-does-not-exist: Datei oder Verzeichnis nicht gefunden
1

Last edited by spirit receiver; 07-06-2006 at 10:20 AM.
 
Old 07-06-2006, 10:16 AM   #9
druuna
LQ Veteran
 
Registered: Sep 2003
Location: the Netherlands
Distribution: lfs, debian, rhel
Posts: 7,514
Blog Entries: 1

Rep: Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140Reputation: 1140
Hi,

Quote:
druuna: your suggestion does work and is quite clever, but unfortunately the head command only filters the second command after the && so I can't catch and limit the output.
The first part (before &&) is there to check if the second part should be executed, the second part can be changed/edited or something else completely:

ls [0-9]* 1>dev/null 2>&1 && echo "Yep, present"
The echo part will only be executed if the first part is true, otherwise the exit status will be 1.

ls [0-9]* 1>/dev/null 2>&1 && ls [0-9]* | grep 31 | head -n 2
All after && will only be executed if the first part is true, otherwise the exit status will be 1.

But using pipetail (or !) is more elegant
 
Old 07-06-2006, 10:22 AM   #10
humbletech99
Member
 
Registered: Jun 2005
Posts: 374

Original Poster
Rep: Reputation: 30
the problem is limited to the command. From the command line I do:
Code:
somecommand -options blah
echo $?
1
but then I do
Code:
somecommand -options same blah | head -n 2
echo $?
141
 
Old 07-06-2006, 10:27 AM   #11
humbletech99
Member
 
Registered: Jun 2005
Posts: 374

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by druuna
Hi,



The first part (before &&) is there to check if the second part should be executed, the second part can be changed/edited or something else completely:

ls [0-9]* 1>dev/null 2>&1 && echo "Yep, present"
The echo part will only be executed if the first part is true, otherwise the exit status will be 1.

ls [0-9]* 1>/dev/null 2>&1 && ls [0-9]* | grep 31 | head -n 2
All after && will only be executed if the first part is true, otherwise the exit status will be 1.

But using pipetail (or !) is more elegant
I fully understand what you are saying but in practice the |head fails to catch the output from the first command which is the whole point. If that was what I wanted to do, I could leave the pipe off altogether and just collect the exit status as normal...
 
Old 07-06-2006, 12:10 PM   #12
raskin
Senior Member
 
Registered: Sep 2005
Location: Russia
Distribution: NixOS (http://nixos.org)
Posts: 1,891

Rep: Reputation: 68
I told you! When you run like this, head gets two lines - and exits. Ah oh who will collect somecommand's output? Nothing? Then somecommand gets SIGPIPE - broken pipe (it is, as head is dead). And surely it exits, as it has no signal handler there. Exit status = 128 + signal nr = 128 + 13 = 141 . Everything as predicted.
 
Old 07-06-2006, 12:20 PM   #13
humbletech99
Member
 
Registered: Jun 2005
Posts: 374

Original Poster
Rep: Reputation: 30
I find that the simplest and best way of doing this is:
Code:
output="`somecommand -options blah`"
result=$?
echo "$output" | head -n 2
This doesn't use a tempfile or anything which is better and is the clearest way I can see of doing this.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash Script- command on exit PDock Programming 6 12-23-2005 07:03 PM
get exit status from a C-program in Bash Yoko Programming 1 07-12-2005 04:33 PM
> Ftp With Exit Status, Ftp with exit status vwvr9 Linux - General 4 02-23-2005 02:53 AM
exit status naflan Programming 2 10-22-2004 12:22 PM


All times are GMT -5. The time now is 03:00 PM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration