From: David Kirkby on 8 Jan 2010 01:59 I've seen alo of the following in scripts, if [ $foo = "sun" ] && [ $bar = "moon" ] ; then if [ "$foo" = "sun" ] && [ $bar = "moon" ] ; then if [ "x$foo" = "xsun" ] && [ "x$bar" = "xmoon" ] ; then if [ x$foo = "xsun" ] && [ x$bar = "xmoon" ] ; then Also, sometime { and } are used. What is the best way to compare things in shell scripts?
From: David W. Hodgins on 8 Jan 2010 03:11 On Fri, 08 Jan 2010 01:59:35 -0500, David Kirkby <drkirkby(a)gmail.com> wrote: > What is the best way to compare things in shell scripts? Always quote variables, unless you have a good reason not to. See http://tldp.org/LDP/abs/html/comparison-ops.html Regards, Dave Hodgins -- Change nomail.afraid.org to ody.ca to reply by email. (nomail.afraid.org has been set up specifically for use in usenet. Feel free to use it yourself.)
From: Stephane CHAZELAS on 8 Jan 2010 03:21 2010-01-7, 22:59(-08), David Kirkby: > I've seen alo of the following in scripts, > > if [ $foo = "sun" ] && [ $bar = "moon" ] ; then > > if [ "$foo" = "sun" ] && [ $bar = "moon" ] ; then > > if [ "x$foo" = "xsun" ] && [ "x$bar" = "xmoon" ] ; then > > if [ x$foo = "xsun" ] && [ x$bar = "xmoon" ] ; then > > Also, sometime { and } are used. > > What is the best way to compare things in shell scripts? They are all wrong except for the 3rd as quotes are placed where they're not necessary (arguments containing no special characters) and not where they are necessary (around variables to avoid special expansion (word splitting and globbing)). [ "$foo" = sun ] && [ "$bar" = moon ] will work in POSIX shells, [ sun = "$foo" ] && [ moon = "$bar" ] [ "x$foo" = xsun ] && [ "x$bar" = xmoon ] [ sunmoon = "$foo$bar" ] [ "x$foo$bar" = sunmoon ] will work in all shells. -- St�phane
From: Geoff Clare on 8 Jan 2010 08:42 Stephane CHAZELAS wrote: > [ "$foo" = sun ] && [ "$bar" = moon ] > > will work in POSIX shells, > > [ sun = "$foo" ] && [ moon = "$bar" ] > [ "x$foo" = xsun ] && [ "x$bar" = xmoon ] > [ sunmoon = "$foo$bar" ] > [ "x$foo$bar" = sunmoon ] > > will work in all shells. The last two will produce false positives if, for example, foo=s and bar=unmoon. (Assuming the last is fixed to have xsunmoon on the rhs.) -- Geoff Clare <netnews(a)gclare.org.uk>
From: David Kirkby on 8 Jan 2010 12:38 On Jan 8, 8:21 am, Stephane CHAZELAS <stephane_chaze...(a)yahoo.fr> wrote: > 2010-01-7, 22:59(-08), David Kirkby: > > > I've seen alo of the following in scripts, > > > if [ $foo = "sun" ] && [ $bar = "moon" ] ; then > > > if [ "$foo" = "sun" ] && [ $bar = "moon" ] ; then > > > if [ "x$foo" = "xsun" ] && [ "x$bar" = "xmoon" ] ; then > > > if [ x$foo = "xsun" ] && [ x$bar = "xmoon" ] ; then > > > Also, sometime { and } are used. > > > What is the best way to compare things in shell scripts? > > They are all wrong except for the 3rd as quotes are placed where > they're not necessary (arguments containing no special > characters) and not where they are necessary (around variables > to avoid special expansion (word splitting and globbing)). > > [ "$foo" = sun ] && [ "$bar" = moon ] > > will work in POSIX shells, > > [ sun = "$foo" ] && [ moon = "$bar" ] > [ "x$foo" = xsun ] && [ "x$bar" = xmoon ] > [ sunmoon = "$foo$bar" ] > [ "x$foo$bar" = sunmoon ] > > will work in all shells. > > -- > Stéphane Thank you Stephane. I wonder if you could answer the following questions, as I'm puzzled why a script is not working as I believe it should. 1) Can you tell me if the following is perfectly safe: if [ ! -x "$SAGE_LOCAL/bin/testcc.sh" ] || [ ! -x "$SAGE_LOCAL/bin/ testcxx.sh" ] ; then echo "testcc.sh and/or testcxx.sh either do not exist, or are not executable" exit 1 fi $SAGE_LOCAL is a directory (in my case /export/home/drkirkby/ sage-4.3.1.alpha1/local). I happen to know that $SAGE_LOCAL will have no spaces in it, but in general would the above work if the path has spaces? Let's for example assume it was "/export/home/drkirkby/this is an alpha release of sage 4.3.1". Can I be sure the above will always work? Is: if [ ! -x ""$SAGE_LOCAL"/bin/testcc.sh" ] || [ ! -x ""$SAGE_LOCAL"/bin/ testcxx.sh" ] ; then echo "testcc.sh and/or testcxx.sh either do not exist, or are not executable" exit 1 fi better or not? If not, is there a better way, and if so how? (By better, I want something that has the best probability of working in any shell - bash, POSIX and preferably some of the more common non- POSIX shells, though I appreciate one can't cover every possibility there.) 2) As you might guess from the names, the scripts test the C and C++ compilers. They do it by detecting what macros are predefined. I do happen to know the scripts will only print something without a space (either GCC, Sun_Studio, HP_on_Tru64, HP_on_HP-UX, IBM_on_AIX, HP_on_Alpha_Linux or Unknown). But in general, lets assume I did not know this fact. How should I test if the two scripts are printing the same thing? If I run them at the command line: drkirkby(a)hawk:~/sage-4.3.1.alpha1$ echo $CC cc drkirkby(a)hawk:~/sage-4.3.1.alpha1$ echo $CXX CC drkirkby(a)hawk:~/sage-4.3.1.alpha1$ local/bin/testcc.sh $CC Sun_Studio drkirkby(a)hawk:~/sage-4.3.1.alpha1$ local/bin/testcxx.sh $CXX Sun_Studio I tried to set two variables like this: C_compiler=`"$(SAGE_LOCAL)"/bin/testcc.sh $CC` C_PLUS_PLUS_compiler=`"$(SAGE_LOCAL)"/bin/testcxx.sh $CXX` but that results in errors when the script is run. /export/home/drkirkby/sage-4.3.1.alpha1/local/bin/sage-spkg: line 317: SAGE_LOCAL: command not found /export/home/drkirkby/sage-4.3.1.alpha1/local/bin/sage-spkg: line 317: /bin/testcc.sh: No such file or directory /export/home/drkirkby/sage-4.3.1.alpha1/local/bin/sage-spkg: line 318: SAGE_LOCAL: command not found /export/home/drkirkby/sage-4.3.1.alpha1/local/bin/sage-spkg: line 318: /bin/testcxx.sh: No such file or directory C_compiler="`$(SAGE_LOCAL)/bin/testcc.sh $CC`" C_PLUS_PLUS_compiler="`$(SAGE_LOCAL)/bin/testcxx.sh $CXX`" does not work. Neither does C_compiler="`"$(SAGE_LOCAL)"/bin/testcc.sh $CC`" C_PLUS_PLUS_compiler="`"$(SAGE_LOCAL)"/bin/testcxx.sh $CXX`" The only thing I've found to semi work is: C_compiler=`$SAGE_LOCAL/bin/testcc.sh $CC` C_PLUS_PLUS_compiler=`$SAGE_LOCAL/bin/testcxx.sh $CXX` but I'm concerned that in general that might not be reliable if SAGE_LOCAL had spaces or other difficult characters. Any ideas of the best way to do this? 3) Using C_compiler=`$SAGE_LOCAL/bin/testcc.sh $CC` C_PLUS_PLUS_compiler=`$SAGE_LOCAL/bin/testcxx.sh $CXX` # Exit if there are a mixture of compilers. if [ "$C_compiler" != "$C_PLUS_PLUS_compiler" ] ; then echo "" echo "ERROR: You have different C and C++ compilers." echo "ERROR The C compiler is $C_compiler, the C++ compiler is $C_PLUS_PLUS_compiler" echo "ERROR: This mixture can not be used to build Sage" echo "ERROR: Ensure both compilers are the same" exit 1 fi fails to produce the expected result, as the output from the script is: ERROR: You have different C and C++ compilers. ERROR The C compiler is Sun_Studio, the C++ compiler is Sun_Studio ERROR: This mixture can not be used to build Sage ERROR: Ensure both compilers are the same Any thoughts on how I can make this bullet proof?
|
Next
|
Last
Pages: 1 2 3 Prev: bash first occurrence in log file Next: select last field of line (cut/sed/awk etc) |