arturo@humming.UUCP (Arturo Perez) (08/14/86)
Here's something I've wanted to do for a while but I can't seem to find the way to do it. In the csh you can do something like ls foo if (! $status) then echo "foo exists" endif The key thing here is the ability to NOT the value of status. How is this similar thing done in Bourne shell. if ! ls foo then echo foo does not exist fi In summary, how can I take the logical NOT of a command's return value in the Bourne shell (which is God's gift to U**X :-)? -- "Life is but a dream" - Lope de Vega "...for some and a NIGHTMARE for others!" Merlin, "Excalibur", the movie Disclaimer? What disclaimer? I can back everything up with as much drivel as you like!
guy@sun.uucp (Guy Harris) (08/16/86)
> The key thing here is the ability to NOT the value of status. How is > this similar thing done in Bourne shell. > > if ! ls foo > then > echo foo does not exist > fi Try if ls foo then : else echo foo does not exist fi The ":" is the pseudo-comment from old Bourne shells; it's really a command that does nothing. Not the cleanest syntax, but that's life. (However, I'd rather have a shell that requires that crud, but allows you to redirect the output of a "for" loop, than one that permits you to negate exit status directly but won't let you redirect the output of loops! At least with the Bourne shell you can get around the inability to negate exit status fairly easily.) However, you may be better off doing if test ! -f foo or something like that; unfortunately, "test" doesn't have a predicate for "just test whether it exists", but you may really want a more restrictive predicate anyway. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)
dce@mips.UUCP (David Elliott) (08/16/86)
In article <150@humming.UUCP> arturo@humming.UUCP (Arturo Perez) writes: >Here's something I've wanted to do for a while but I can't seem to find the >way to do it. > >In the csh you can do something like > >ls foo >if (! $status) then > echo "foo exists" >endif > >The key thing here is the ability to NOT the value of status. How is >this similar thing done in Bourne shell. > Wrong. The key thing here is the ability to evaluate an expression. Though not built in to most versions of sh, the 'test' command can be used for a similar effect, as can 'expr', and you can always use 'case'. Here are three ways: 1. The 'test' command (this also exists as '[' in many systems, so I'll use that here) ls foo if [ $? -eq 0 ] then echo "exists" fi 2. The 'expr' command (since this prints the boolean truth value, we throw the output away) ls foo if expr $? != 0 >/dev/null then echo "exists" fi 3. The 'case' statement ls foo case "$?" in 0) echo "exists" ;; esac There are two problems with this: 1. You have programmed-in knowledge that '0' is 'true' (this isn't really so bad). 2. If 'foo' doesn't exist, 'ls' may still exit with a 0. A quick look at the 4.3BSD code proves me out. What is really needed here is what Guy Harris suggested, which is: if [ -f foo ] then echo "exists" fi except that '[ -f foo ]' only returns true if 'foo' is a regular file. This brings up a couple of really strange (but valid) examples: case `echo foo*` in "foo" | "foo "*) echo "exists" ;; esac # 'dummy' ensures proper 'for' syntax for i in foo* dummy { case "$i" in "foo") echo "exists" break ;; esac } (Excuse the prodigious use of quotes. I'm a "fanatic".) David Elliott {ucbvax,decvax,ihnp4}!decwrl!mips!dce
levy@ttrdc.UUCP (Daniel R. Levy) (08/17/86)
In article <150@humming.UUCP>, arturo@humming.UUCP (Arturo Perez) writes: >In the csh you can do something like > >ls foo >if (! $status) then > echo "foo exists" >endif > >The key thing here is the ability to NOT the value of status. How is >this similar thing done in Bourne shell. > >if ! ls foo >then > echo foo does not exist >fi To follow your example literally: ls foo if test $? -ne 0 # or, "if [ $? -ne 0 ]" is supported by modern /bin/sh's then echo foo does not exist fi Of course, there are other ways to check for nonexistence of foo, e.g.: if [ ! -f foo -a ! -d foo -a ! -p foo -a ! -c foo -a ! -b foo ] # foo is not a file, a directory, a pipe, a character special device, or a # block special device which though "wordier" does not require the spawning of another process presuming that "test" is a builtin in your shell. -- ------------------------------- Disclaimer: The views contained herein are | dan levy | yvel nad | my own and are not at all those of my em- | an engihacker @ | ployer or the administrator of any computer | at&t computer systems division | upon which I may hack. | skokie, illinois | -------------------------------- Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, go for it! allegra,ulysses,vax135}!ttrdc!levy
chris@pixutl.UUCP (chris) (08/18/86)
You can also do: ( ls foo ) || echo not there or, more cheaply: { ls foo ; } || echo not there and if you didn't want to see the output of the ls command, { ls foo >/dev/null 2>&1 ; } || echo not there Chris -- Chris Bertin : (603) 881-8791 x218 xePIX Inc. : 51 Lake St : {allegra|ihnp4|cbosgd|ima|genrad|amd|harvard}\ Nashua, NH 03060 : !wjh12!pixel!pixutl!chris
anw@nott-cs.UUCP (08/20/86)
In article <6228@sun.uucp> guy@sun.uucp (Guy Harris) writes: >Try > > if ls foo > then > : > else > echo foo does not exist > fi Or you could try ls foo || echo foo does not exist In complicated situations, "if ... then ... else ... fi" is clearer, but where there is only one subsidiary command I think "&&" and "||" can tidy up shell scripts quite a lot. I often use (V7 with SV shell) something like [ -w foo ] || fault "can't write to foo" where "fault" is a suitable function, such as fault () { echo $0: error, "$@" 1>&2; exit 1; } -- Andy Walker, Maths Dept, Nottm Univ
swa@COMET.LCS.MIT.EDU (Steven Augart) (08/21/86)
From: Arturo Perez <arturo%humming.uucp@BRL.ARPA> Date: 14 Aug 86 14:12:45 GMT In the csh you can do something like ls foo if (! $status) then echo "foo exists" endif (parenthetical note: "ls" will return status 0 whether or not it can find foo. The example is faulty). The key thing here is the ability to NOT the value of status. How is this similar thing done in Bourne shell. Can't be done directly in the Bourne shell, since the Bourne shell simply doesn't have C-shell style expressions; they are handled separately by the "test" and "expr" programs. Since the bourne shell doesn't have expressions, it also doesn't have an internal NOT operator. However, you can do this simple workaround (or you could if "ls foo" returned 0 status to indicate that it found "foo" and nonzero status to indicate that it hadn't found "foo"): if ls foo then ; else echo "foo not found" endif Steven Augart MIT Laboratory for Computer Science swa@xx.lcs.mit.edu, swa@xx.ARPA
ignatz@aicchi.UUCP (Ihnat) (08/22/86)
There may be more elegant ways--it's sometimes tough to be elegant at 2:50 AM--but certainly, for filename FILE ls FILE >/dev/null 2>/dev/null if [ ! $? ] then <whatever negated thingies you want> fi; works. (As we all know, $? is the return code from the last executed command.) However, if just testing existence, how about if [ -f FILE ] then <etc> fi; Look at test(1); it's got a lot of nifty cases you can test... -- Dave Ihnat Analysts International Corporation (312) 882-4673 ihnp4!aicchi!ignatz || ihnp4!homebru!ignatz
hahn@ames-prandtl.arpa (Jonathan Hahn) (08/23/86)
In article <150@humming.UUCP>, arturo@humming.UUCP (Arturo Perez) writes: >In the csh you can do something like > >ls foo >if (! $status) then > echo "foo exists" >endif > >The key thing here is the ability to NOT the value of status. How is >this similar thing done in Bourne shell. > >if ! ls foo >then > echo foo does not exist >fi I haven't seen any mention of our Bourne shell friend "||". How about (assuming ls returns correct status): ls foo || echo foo does not exist If you want to get rid of the output and error messages from ls: ls foo > /dev/null 2>&1 || echo foo does not exist And if you want a complex second statement: ls foo || { echo foo does not exist exit } -jonathan hahn NAS Program, Ames Research Center Moffett Field, CA hahn@ames-nas
ado@elsie.UUCP (Arthur David Olson) (08/24/86)
> I haven't seen any mention of our Bourne shell friend "||". How about > (assuming ls returns correct status): > > ls foo || echo foo does not exist For the truly esoterically minded (especially those who don't want to run "ls" or "test" or any other non-built-ins on BSD systems): case fo[o] in foo) ;; *) echo foo does not exist ;; :-) ;; esac -- UNIX is an AT&T Bell Laboratories trademark (or an AT&T registered trademark). -- UUCP: ..decvax!seismo!elsie!ado ARPA: elsie!ado@seismo.ARPA DEC, VAX, Elsie & Ado are Digital, Borden & Ampex trademarks.
david@ukme.UUCP (David Herron, NPR Lover) (09/01/86)
In article <3220@brl-smoke.ARPA> swa@COMET.LCS.MIT.EDU (Steven Augart) writes: > if ls foo > then > ; > else > echo "foo not found" > endif Or: #! /bin/sh # not.sh -- Logical NOT of the return status of a command # # USAGE: not command # if $@; then exit 1 else exit 0 fi Allowing one to say: if not rsh e /bin/true; then echo ^G^Ge is down^G^G fi -- David Herron, cbosgd!ukma!david, david@UKMA.BITNET, david@ms.uky.csnet (I'm also "postmaster" at all those addresses) (And "news" and "netnews" and "uucp" and ....)
sja@ih1ap.UUCP (Steve Alesch) (09/12/86)
In article <6228@sun.uucp>, guy@sun.uucp (Guy Harris) writes: > > The key thing here is the ability to NOT the value of status. How is > > this similar thing done in Bourne shell. > > > > if ! ls foo > > then > > echo foo does not exist > > fi > > Try > > if ls foo > then > : > else > echo foo does not exist > fi > > The ":" is the pseudo-comment from old Bourne shells; it's really a command > that does nothing. > > Not the cleanest syntax, but that's life. (However, I'd rather have a shell > that requires that crud, but allows you to redirect the output of a "for" > loop, than one that permits you to negate exit status directly but won't let > you redirect the output of loops! At least with the Bourne shell you can > get around the inability to negate exit status fairly easily.) > > However, you may be better off doing > > if test ! -f foo > > or something like that; unfortunately, "test" doesn't have a predicate for > "just test whether it exists", but you may really want a more restrictive > predicate anyway. Correct me if I'm missing something. What's wrong with: ls foo if [ $? != 0 ]; then echo foo does not exist fi -- Steve Alesch AT&T (312)510-7881, ...!ihnp4!ih1ap!sja
chris@pixutl.UUCP (chris) (09/16/86)
> > Correct me if I'm missing something. What's wrong with: > > ls foo > if [ $? != 0 ]; then > echo foo does not exist > fi > -- > > Steve Alesch AT&T > (312)510-7881, ...!ihnp4!ih1ap!sja It should be: if [ $? -ne 0 ]; then '!=' is used to compare strings, -ne and family, integers... :-) Chris -- Chris Bertin : (603) 881-8791 x218 xePIX Inc. : 51 Lake St : {allegra|ihnp4|cbosgd|ima|genrad|amd|harvard}\ Nashua, NH 03060 : !wjh12!pixel!pixutl!chris
dianeh@ism780c.UUCP (Diane Holt) (09/17/86)
In article <574@ih1ap.UUCP> sja@ih1ap.UUCP (Steve Alesch) writes: >In article <6228@sun.uucp>, guy@sun.uucp (Guy Harris) writes: >> > The key thing here is the ability to NOT the value of status. >> > How is this similar thing done in Bourne shell. >> > if ! ls foo >> > then >> > echo foo does not exist >> > fi >> >> Try >> if ls foo >> then >> : >> else >> echo foo does not exist >> fi >> [or] >> if test ! -f foo >> >Correct me if I'm missing something. What's wrong with: > ls foo > if [ $? != 0 ]; then > echo foo does not exist > fi I didn't see the original posting, so I'm not sure exactly what's trying to be done, but my suggestion would be: ls foo || echo "foo does not exist" The || is "OR" -- return "true" from the first command "OR" execute the next one. Double ampersand (&&) is used to check the return from the first command "AND" execute the next one. There is no limit on how many "next" commands there can be or any restrictions on combinations of "OR"s and "AND"s. I use this all the time. P.S. Obviously, this whole example is pretty silly, since 'ls' will output "foo not found", if it doesn't really exist, so echoing that it doesn't is superfluous...but I'm assuming that the command used is just an example and not significant to the original poster's question...if it really *is* significant, then you'd want to redirect the output: ls foo >/dev/null 2>&1... Diane Holt Interactive Systems Corp. Santa Monica, CA {seismo,decvax,cbosgd}!hplabs!sdcrdcf!ism780c!dianeh "But I don't know anything about computers." "Nobody does...but don't you want one for when you do find out?"
guy@sun.uucp (Guy Harris) (09/17/86)
> Correct me if I'm missing something. What's wrong with: > > ls foo > if [ $? != 0 ]; then > echo foo does not exist > fi It doesn't indicate quite as clearly as the other version that the failure/success of "ls" is being tested. It merely indicates that the exit status of "ls" is being compared against 0; you have to associate this with failure/success. (See past discussions in net.lang.c about why Boolean types exist even if you language happens to implement them as integral types.) In addition, 1) "ls" does not always return an exit status indicating whether it could find the files in question or not and 2) "ls" *does* always print the name of the file, if it finds it, or an error, if it doesn't. If "test" had a "does this file exist" predicate, then as I mentioned that would be what you should use. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)
lilly@leadsv.UUCP (Harriette Lilly) (09/27/86)
Speaking of C shells..... I am just getting into some deep shell programming and have exausted (I think ) the resources here.... I would like to find someone (or more than one) that I could exchange E-mail with about shells and possibly get some answers to some problems I am having. Any help in this area would be greatly appreciated. Thanx in advance.... Harriette @ Lockheed for Telos Consulting
lilly@leadsv.UUCP (Harriette Lilly) (09/29/86)
Thanks to those who answered, I will be writting you soon as if figure out how :-) P.S. I already have the UNIX C SHELL Field Guide, But even it it not answering all my questions.