kirkaas@oahu.cs.ucla.edu (paul kirkaas) (10/23/89)
How can one say "if not" in a shellscript; that is, execute the body of the "then" only if the argument of "if" returns a non-zero exit status? I would like something like: if ! TESTCOMMAND then BODY fi Stupid question? Trivial answer? I hope so. Thanks. Paul Kirkaas kirkaas@cs.ucla.edu
maart@cs.vu.nl (Maarten Litmaath) (10/24/89)
kirkaas@oahu.cs.ucla.edu (paul kirkaas) writes:
\How can one say "if not" in a shellscript; that is, execute the body of
\the "then" only if the argument of "if" returns a non-zero exit status?
Unfortunately there doesn't seem to be a clean way to do this.
The obvious work-around:
if command
then
:
else
command
fi
A cleaner approach:
if not command
then
command
fi
...where `not' is defined as the following shell function/script:
${1+"$@"}
test $? != 0
SunOS 4.0.3c /bin/sh doesn't like a function to be named `!', a shell
script would be OK though.
--
A symbolic link is a POINTER to a file, | Maarten Litmaath @ VU Amsterdam:
a hard link is the file system's GOTO. | maart@cs.vu.nl, mcsun!botter!maart
merlyn@iwarp.intel.com (Randal Schwartz) (10/24/89)
In article <28381@shemp.CS.UCLA.EDU>, kirkaas@oahu (paul kirkaas) writes: | How can one say "if not" in a shellscript; that is, execute the body of | the "then" only if the argument of "if" returns a non-zero exit status? | | I would like something like: | | if ! TESTCOMMAND | then | BODY | fi | | Stupid question? Trivial answer? I hope so. Thanks. Yeah. if TESTCOMMAND then : nada else BODY fi Easy. Just another Bourne-again hacker, -- /== Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ====\ | on contract to Intel's iWarp project, Hillsboro, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!uunet!iwarp.intel.com!merlyn | \== Cute Quote: "Welcome to Oregon... Home of the California Raisins!" ==/
hitz@auspex.auspex.com (Dave Hitz) (10/24/89)
In article <28381@shemp.CS.UCLA.EDU> kirkaas@oahu.UUCP (paul kirkaas) writes: >How can one say "if not" in a shellscript; that is, execute the body of >the "then" only if the argument of "if" returns a non-zero exit status? > >I would like something like: > >if ! TESTCOMMAND >then > BODY >fi I often define the following in my shell scripts. NOT() { if ${1+"$@"} then return 1; else return 0; fi } Unfortunately, not all shells support functions yet, but for those that do this works fine. You can use this just like you requested: if NOT grep foobar /etc/passwd >&- then BODY fi Picky people may observe that the arguments to NOT get expanded by the shell twice, but I've never been caught by this. -- Dave Hitz home: 408-739-7116 UUCP: {uunet,mips,sun,bridge2}!auspex!hitz work: 408-970-8970
ag@cbmvax.UUCP (Keith Gabryelski) (10/24/89)
In article <3787@solo6.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: >kirkaas@oahu.cs.ucla.edu (paul kirkaas) writes: >\How can one say "if not" in a shellscript; that is, execute the body of >\the "then" only if the argument of "if" returns a non-zero exit status? It is actually a toss up for me between: > if not command > then > command > fi > >...where `not' is defined as the following shell function/script: > > ${1+"$@"} > test $? != 0 and until command do : # do some stuff break # explict break done Agreed that there should be a cleaner way. Pax, Keith -- "It took no computation to dance to the rock 'n roll station" -- VU ag@cbmvax.commodore.com Keith M. Gabryelski ...!uunet!cbmvax!ag
ok@cs.mu.oz.au (Richard O'Keefe) (10/24/89)
When you really want to write unless command ; then stmts fi you can do it by writing command if test $? != 0 ; then # command failed stmts fi If stmts is sufficiently simple, you can also do command || { stmts }
mrm@sceard.Sceard.COM (M.R.Murphy) (10/24/89)
>kirkaas@oahu.cs.ucla.edu (paul kirkaas) writes: >How can one say "if not" in a shellscript; that is, execute the body of >the "then" only if the argument of "if" returns a non-zero exit status? Might be a Good Thing to look up how && and || work, especially with { and }. -- Mike Murphy Sceard Systems, Inc. 544 South Pacific St. San Marcos, CA 92069 mrm@Sceard.COM {hp-sdd,nosc,ucsd,uunet}!sceard!mrm +1 619 471 0655
steinbac@hpl-opus.HP.COM (Gunter Steinbach) (10/25/89)
I prefer This form:
TESTCOMMAND || {
BODY
}
It doesn't allow an "else" clause, though.
roe@sobmips.UUCP (r.peterson) (10/25/89)
From article <2558@auspex.auspex.com>, by hitz@auspex.auspex.com (Dave Hitz): > In article <28381@shemp.CS.UCLA.EDU> kirkaas@oahu.UUCP (paul kirkaas) writes: >>How can one say "if not" in a shellscript; that is, execute the body of >>the "then" only if the argument of "if" returns a non-zero exit status? >> >>I would like something like: >> >>if ! TESTCOMMAND >>then >> BODY >>fi > > I often define the following in my shell scripts. [function deleted] > Unfortunately, not all shells support functions yet, but for those that > do this works fine. You can use this just like you requested: > > if NOT grep foobar /etc/passwd >&- > then > BODY > fi > how about: TESTCOMMAND if [ ! $? -eq 0 ] then BODY fi ie: grep foobar /etc/passwd >/dev/null 2>&1 if [ ! $? -eq 0 ] OR: if test ! $? -eq 0 then BODY fi -- If the brain were so simple we understood it|Roe Peterson We would be so simple we couldn't. |{attcan,mcgill-vision}!sobeco!roe
roe@sobmips.UUCP (r.peterson) (10/26/89)
From article <63720010@hpl-opus.HP.COM>, by steinbac@hpl-opus.HP.COM (Gunter Steinbach): > I prefer This form: > > TESTCOMMAND || { > BODY > } > > It doesn't allow an "else" clause, though. I tried this: true && { echo true } || { echo false } and it functions fine. Change true && to false && and it prints false correctly as well. -- If the brain were so simple we understood it|Roe Peterson We would be so simple we couldn't. |{attcan,mcgill-vision}!sobeco!roe
steinbac@hpl-opus.HP.COM (Gunter Steinbach) (10/27/89)
From article <1989Oct26.041244.28325@sobmips.UUCP>, by roe@sobmips.UUCP (r.peterson): > I tried this: > true && { > echo true > } || { > echo false > } > and it functions fine. Change true && to false && and it prints false > correctly as well. Neato! I like it. But... You have to be careful with nontrivial commands in the first command group (the if true group): Add a "false" command after the first echo in your example, and it prints out both "true" and "false" - not at all what you wanted. So it is not a true "else" that only refers to the original test. Guenter Steinbach | hplabs!gunter_steinbach | gunter_steinbach@hplabs.hp.com
maart@cs.vu.nl (Maarten Litmaath) (10/27/89)
roe@sobmips.UUCP (r.peterson) writes: \... \true && { \ echo true \} || { \ echo false \} \ \and it functions fine. Change true && to false && and it prints false \correctly as well. The abovementioned method has different characteristics: test-command && { if-clause } || { else-clause } ...will execute the else-clause if the test-command *or* the if-clause fails, which might not be what you want. -- A symbolic link is a POINTER to a file, | Maarten Litmaath @ VU Amsterdam: a hard link is the file system's GOTO. | maart@cs.vu.nl, mcsun!botter!maart
chip@ateng.com (Chip Salzenberg) (10/28/89)
Several people, including Dave Hitz, suggest variations on: NOT() { ${1+"$@"} test $? -ne 0 } I love it! It's simple and it works. However, Dave Hitz asserts: >Picky people may observe that the arguments to NOT get expanded by >the shell twice, but I've never been caught by this. In fact, they do not get expanded twice. The effect of "$@", as opposed to "$*", is to expand the shell function's arguments as if they were _individually_ quoted. Thus they will not be expanded (again) in the shell function. Unfortunately, if $# is zero, "$@" expands to "" instead of nothing. Thus the need for the ${1+"$@"} hack. [sigh] -- You may redistribute this article only to those who may freely do likewise. Chip Salzenberg at A T Engineering; <chip@ateng.com> or <uunet!ateng!chip> "'Why do we post to Usenet?' Naturally, the answer is, 'To get a response.'" -- Brad "Flame Me" Templeton