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!
gwyn@brl-smoke.ARPA (Doug Gwyn ) (08/16/86)
In article <150@humming.UUCP> arturo@humming.UUCP (Arturo Perez) writes: >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 :-)? Here is how the .funcs function-definition file I source from my .profile does it: not(){ $* if [ $? -eq 0 ] then return 1 else return 0 fi } So I can then use this new "not" command as in: if not stuff ... then whatever fi Another more direct trick is: if stuff ... then : else whatever fi
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
arturo@humming.UUCP (Arturo Perez) (08/20/86)
In article <??.arturo@humming.uucp> arturo@humming.UUCP 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 > >However, you may be better off doing > > if test ! -f foo > > Guy Harris > guy@sun.com (or guy@sun.arpa) [Also suggested by Chris Torek <..!seismo!mimsy.umd.edu!umcp-cs!chris>, harvard!g.cs.cmu.edu!Bennet.Yee, Stu Heiss <..!ihnp4!jpusa1!stu>, and David Harrison <harvard!seismo!mnetor!utfyzx!harrison>] I guess I confused everyone. What I meant was I wanted a method to directly not the status of a command in an if statement. I don't want to single Guy out but his answer was typical of the response I got (much more nicely worded than some, too). Here are some more: >From seismo!rick From: Rick Adams <harvard!seismo!rick> $? is equivalent to $status. test it the same way you did in csh >From caip!princeton!allegra!ho95e!wcs Look at the man pages for test(1) and sh(1), in particular the sections on standard variables. $? is the return code of the previous command, so you can say foo if [ "$?" != 0 ] then echo "no foo" else echo "foo worked" fi On most Bourne shell versions, and ksh, test is usually a built-in, and "[" is a built-in alias for test. You can't say if [ ! "$?" ] because that means "if "$?" is not empty-string", and $? always has a value. [This is a useful bit of shell lore] From: harvard!caip!princeton!allegra!ulysses!dgk (David Korn) Just use the || operator command || failure_command [Also suggested by Robert C. Chancer <homxb!rcc>] >From caip!clyde!cbatt!cbdkc1!cbnap!whp How 'bout: ls mojo if [ ! $? ] then echo foo else echo bar fi >From: harvard!violet!seismo!ucb-vax.ARPA!jason Try combinations for test ([) and expr. From topaz!pegasus!hansen csh: ls foo if (! $status) then echo "foo exists" endif sh: ls foo if [ $? != 0 ]; then echo "foo exists" endif If you have the System Vr2 (or later) sh (also available on SUN 3.0) or the ksh, then you can do the following: not() { if eval "$@"; then return 1; else return 0; fi; } and use it exactly as you indicated: if not ls foo then echo foo does not exist fi Tony Hansen ihnp4!pegasus!hansen I think Tony Hansen's answer is the most useful for me. Using his Bourne shell not function I can arbitrarily not the return status of any command in a concise way. This is important because it is SO easy to write non-readable shell scripts. Thank you all! -- "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!
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
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
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.