ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I've got a 'nested' for loop which has a grep in it, if the grep fails there's no output - however the error code is still $0 and the second for loop is still entered, there's also a grep in the second for loop.
I guess ultimately what i need to know is whether there's a way of making grep generate an error code. when no results are found?
Distribution: Solaris 9 & 10, Mac OS X, Ubuntu Server
Posts: 1,197
Rep:
You'll probably have to show a script segment. If you just do a grep on the command line and then immediately echo $?, you will see that it returns a code. You need to capture that code in your script before anything else is done that changes $?.
EXIT STATUS
Normally, the exit status is 0 if selected lines are found and 1
otherwise. But the exit status is 2 if an error occurred, unless the
-q or --quiet or --silent option is used and a selected line is found.
Note, however, that POSIX only mandates, for programs such as grep,
cmp, and diff, that the exit status in case of error be greater than 1;
it is therefore advisable, for the sake of portability, to use logic
that tests for this general condition instead of strict equality
with 2.
Gonna need some help with this, will post 'similar' code tomorrow but basically my oneliner enters a for loop which grabs a uuid (have some perl to echo a none zero exit code if theres no match) this uuid is then used in another for loop (again using perl for the none zero exit code thing) to list virtual server snapshots (specificall the snapshot uuid). This then reverts to a specified snapshot - essentially it's a one liner to rewind xen snapshots, but if insert incorrect info in either of my for loops the exit code is always zero - if I run the code outside the for loop the exit code is always nonezero. Hard to explain without an example... This is psuedocode, expect something which actually works tomorrow at some point:
Code:
for uuid in `list virtual servers | grep 'correct-server' | perl -alne '{ print $F[4] } END { exit($.==0) }'`;
do
for snapshotuuid in `list virtual snapshot | grep $uuid | grep snaoshotname | perl -alne '{ print $F[4] } END { exit($.==0) }'`;
do
revert $uuid to $snapshotuuid;
done;
done;
for UID in `xe vm-list | grep -B1 VMNAME | grep uuid | perl -alne '{ print $F[4] } END { exit($.==0) }'`; do for SNAP in `xe snapshot-list snapshot-of=$UID | grep -B1 SNAPSHOTNAME | grep uuid | perl -alne '{ print $F[4] } END { exit($.==0) }'`; do xe snapshot-revert uuid=$SNAP; done; done;
VMNAME and SNAPSHOTNAME are legitimate values. With the correct values my exit status is 0, with incorrect values - my exit status is still 0... I'm happy for people to find alternative methods of achieving the same thing, but it really needs to be as short as possible.
In any sequence like that, the exit status after the sequence is going to be that of the last command in the sequence. No way around that. So, you have to break it up if you want an intermediate exit status.
Something like:
Code:
if xe vm-list | grep -A1 NOTREAL > scratch; then
cat scratch | grep power | awk '{print $5}';
else
...
fi
The exit status of the `grep -A1 NOTREAL` controls the if, and it's output goes to the file scratch. Then in the next line you can continue with `cat scratch` piped to whatever else you wanted to do.
In any sequence like that, the exit status after the sequence is going to be that of the last command in the sequence. No way around that. So, you have to break it up if you want an intermediate exit status.
Something like:
Code:
if xe vm-list | grep -A1 NOTREAL > scratch; then
cat scratch | grep power | awk '{print $5}';
else
...
fi
The exit status of the `grep -A1 NOTREAL` controls the if, and it's output goes to the file scratch. Then in the next line you can continue with `cat scratch` piped to whatever else you wanted to do.
I solved this with my perl code above. I can do it without 'breaking it up'. The perl doesn't work with my loop though (each individual line does, but just not the loop itself).
Last edited by genderbender; 11-04-2010 at 06:35 AM.
$ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
...
Exit Status:
Returns the status of the last command executed.
From a few tests I ran, it seems that "last command" refers only to commands in the body of the loop (i.e. COMMANDS). I think the easiest way to solve this problem is to use a flag variable:
Code:
status=1
for uuid in ...
do
for snapshotuuid in ...
do
revert $uuid to $snapshotuuid && status=0
done;
done;
exit $status
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.