sh$ true && echo aaa aaa
sh$ true && echo aaa aaa
sh$ true || echo aaa
sh$ false && echo aaa
sh$ false || echo aaa aaa
$ if true; then echo yes; else echo no; fi yes
$ if false; then echo yes; else echo no; fi no
$ if echo something | grep .; then echo found; else echo no; fi something found
equal: STRING1 = STRING2 not equal: STRING1 != STRING2
fret=$? # get func ret code if [ $fret != 0 ] ; then # wget returned error $echo "Download error.\nNo log written." else
[ "0$show" -ge "2" ] && set -xv [ "0$show" -eq "1" ] && set -x
INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2
-ge -gt -le -lt -ne
[-n] STRING the length of STRING is nonzero
-z STRING the length of STRING is zero
[ -n "$Trig1" -a -n "$Trig1" ] && { action if both trigger is set. } [ -z "$Trig1" -a -z "$Trig1" ] || { action if either trigger is set }
[ "$Trig1" -o "$Trig1" ] || { [ -z "$Trig1" -a -z "$Trig1" ] && { action if neither trigger is set. ie, if either trigger is set, there will be no such action. }
True if EXPR is false.
True if both EXPR1 and EXPR2 are true.
True if either EXPR1 or EXPR2 is true.
$ [ "T" -a "" ] && echo yes
$ [ "T" -a "T" ] && echo yes yes
$ [ "" -a "T" ] && echo yes
host:~/bin>if ( -f dofor ) echo aaa aaa
host:~/bin>if ( "a"=="a" ) echo aaa if: Expression Syntax.
host:~/bin>if ( "a" == "a" ) echo aaa aaa
$ touch aa $ dir aa -rw------- 1 suntong glan 0 Dec 7 13:19 aa $ [ -f aa ] && echo aa aa $ [ -s aa ] && echo aa $
-e FILE FILE exists
-f filename True if filename exists and is a regular file. -s filename True if filename exists and has a size greater than zero.
If you want to test a varible is empty or not, you can either say
[ $var ] or [ "$var" ]
But if you can't guarantee that $var is only one word, you'll get error "[: too many arguments"
documented on: 1999.12.21 Tue 09:20:03
b='' b=T
[ "$b" ] && echo b is not empty! # way to test empty! [ "$b" ] || echo b is empty! # way to test not empty!
if [ "$b" ] ; then echo b is true! ; else echo b is false; fi
[ "$b" ] || echo b is empty! # lazy way to test not empty! [ -z "$b" ] && echo b is empty. # formal way to test empty! [ ! -z "$b" ] && echo b is not empty. # formal way to test empty!
b='' if [ "$b" ] ; then echo b is true! ; fi if [ ! "$b" ] ; then echo b is false! ; fi
yield:
+ [ ] + [ ! ] /home/users/suntong/bin/sh.test.script: test: argument expected
Right way:
[ "$b" ] && echo b is not empty! # way to test empty! [ "$b" ] || echo b is empty! # way to test not empty!
this will not work:
printf "Writing to " >&2 # for "txt" command with no 'saved_name' parameter provided, # write to stdout instead of saving to file if [ "$1" ] || [ $sfunc = txt ] ; then printf "standard output" >&2 save_to= else save_to=T # will save fi
+ printf Writing to Writing to + [ aaaa ] + printf standard output
use [ -z ] !
_empty_test(){ if [ "$1" ]; then echo "\$1=$1"; else echo "\$1 is empty"; fi echo "== ${1-minus}, ${1+plus}\n" } empty_test(){ val1=$1; val2=${1+"$@"}; _empty_test $val2 ; _empty_test "$val2" ; # different! }
calls: call empty_test with ''
![]() |
!! |
+ empty_test val1= val2= + _empty_test + [ ] + echo $1 is empty $1 is empty + echo == minus, \n
+ _empty_test + [ ] + echo $1 is empty $1 is empty + echo == , plus\n
[ ] will always tells you that string is empty
but ${+} and ${-} can tell the difference!
empty_test 'a' 'b' + empty_test a b val1=a val2=a b + _empty_test a b + [ a ] + echo $1=a $1=a + echo == a, plus\n
+ _empty_test a b + [ a b ] + echo $1=a b $1=a b + echo == a b, plus\n
![]() |
!! |
so we can see passing $val2 or "$val2" is different
documented on: 1999.12.06 Mon 12:02:39
:~/bin$ if [ "a" = "a" ] ; then echo aaa ; fi aaa
:~/bin$ if [ "a"="a" ] ; then echo aaa ; fi aaa
:~/bin$ if ["a"="a"] ; then echo aaa ; fi bash: [a=a]: command not found
if [ "$2" = "" -o "$2" = "@" ] then saved_name=`basename $url` else saved_name=$2 fi
documented on: Sun 04-04-99
> According to several man pages I got, the commands are -h, -l and -L. > What should I choose when doing the shell script programming?
Welcome to the wonderful world of Unix, where people never seem te be able to agree on such simple things. The answer is, unfortunately, "It depends what Unix you are on".
> Correct me if I'm wrong: > I think the gnu flavor is -L, that is bash's buildin test and test from > gnu (.../gnu/test) use -L. (and ksh)
Correct.
> sh also has buildin test? because:
Yes.
> and sh buildin test for symbolic link files is -h and (?) -L. > Is above correct?
See the local man sh, where the builtin 'test' is documented.
> But why when it comes to real testing, I got weird results?
> sh > $ ls -l index.htm > lrwxrwxrwx 1 tongsun glan 31 Nov 5 11:11 index.htm -> > ../../... > $ [ -h index.htm ] && echo aa > aa > $ [ ! -h index.htm ] && echo aa > $
> hmm..., seems good, but how about:
> sh > $ [ -L index.htm ] && echo aa > test: argument expected > why?
The -L is not a recognized flag for the built-in '[' command.
> besides,
> $ test " -l index.htm" && echo no > no > $ test "! -l index.htm" && echo no > no > $ test "-h index.htm" && echo aa > aa > $ test "! -h index.htm" && echo aa > aa ... > what's going here, why test is always true?
Because you pass all these tests A SINGLE argument. If you write "-h index.htm" (in double quotes) then that is a single argument which is evaluated a test "is this string not empty". Since this is true in ALL the above cases, you get the above results.
try:
$ test -l index.htm && echo no
And it will work much better.
Ruurd.
``test -h'' works on FreeBSD 4.0, HP-UX 11.10, and DEC UNIX 5.0.
ksh on DEC UNIX 5.0:
$ type test test is a shell builtin $ touch File1 $ ln -s File1 File2 $ test -h File1 && echo "File1 is a symlink." $ test -h File2 && echo "File2 is a symlink." File2 is a symlink. $ /bin/test -h File1 && echo "File1 is a symlink." $ /bin/test -h File2 && echo "File2 is a symlink." File2 is a symlink. $
The behavior is the same for HP-UX and FreeBSD.
> and sh buildin test for symbolic link files is -h and (?) -L. > Is above correct?
Yes.
> $ test " -l index.htm" && echo no > no
And I've got no evidence an "-l" flag exists. Plus arguments aren't going to be separated if you put quotes around them! All the following tests will pass!
Example:
$ test "abc" && echo Passed. Passed. $ test "abcdeffg hijklmnop" && echo Passed. Passed.
Chris Costello
documented on: 1999.11.09 Tue 10:45:41
The -L or -H option to test.
if [ -h <file> ]; then echo "It is a symbolic link" fi
if [[ -L ${FILE} ]]; then : symlink else : not a symlink fi
-L file True if file exists and is a symbolic link.
no -h option
but -L can't be used in sh scripts! :
$ [ -L tree ] && echo aaa test: argument expected
documented on: 11:38:03
iitrc:~/temp$ unset sc; [ "$sc" == "1" ] && echo aaa iitrc:~/temp$ sc=0; [ "$sc" == "1" ] && echo aaa iitrc:~/temp$ sc=1; [ "$sc" == "1" ] && echo aaa aaa
iitrc:~/temp$ [ $sc ] && echo aaa iitrc:~/temp$ sc=1 iitrc:~/temp$ [ $sc ] && echo aaa aaa iitrc:~/temp$ sc=0 iitrc:~/temp$ [ $sc ] && echo aaa aaa
— sc not defined, no show
— sc defined, no matter 0 or 1, show
iitrc:~/temp$ [ \!\$sc ] && echo aaa aaa iitrc:~/temp$ sc=1 iitrc:~/temp$ [ \!\$sc ] && echo aaa aaa
— the same as to !$sc
iitrc:~/temp$ [ $sc == 1 ] && echo aaa aaa iitrc:~/temp$ sc=0 iitrc:~/temp$ [ $sc == 1 ] && echo aaa iitrc:~/temp$
— yeah, this is the right way
iitrc:~/temp$ unset sc iitrc:~/temp$ [ $sc == '1' ] && echo aaa [: ==: unary operator expected
— new problem
iitrc:~/temp$ [ $sc ] && [ $sc == '1' ] && echo aaa iitrc:~/temp$ sc=1; [ $sc ] && [ $sc == '1' ] && echo aaa aaa iitrc:~/temp$ sc=0; [ $sc ] && [ $sc == '1' ] && echo aaa iitrc:~/temp$
— Got it!
documented on: 05-04-99 20:35:04
> How can I assign boolean value to a varible and test it later: > > if [ $b ] ; then echo b is true! ; fi > if [ !$b ] ; then echo b is false! ; fi > the above code will say that b is both true & false no matter what > value I give to b: 0,1, true & false.
man test — the contents of b are not parsed, it just checks whether it's set to something or not:
$ b=
$ if [ "$b" ] ; then echo empty string = true > else echo empty string = false; fi empty string = false
$ b=something
$ if [ "$b" ] ; then echo non-empty string = true > else echo non-empty string = false; fi non-empty string = true
/* era */
Old-timers use `case': it's always been a shell builtin.
b=0 ... case $b in 0) echo b is still zero ;; *) echo b is no longer zero ;; esac
Tim.
documented on: 1999.09.22 Wed 15:19:48
> # Is there a nice way to check if any of a group of files > # exists using a wildcard? I don't want to get the pesky > # "No match" messages from ls or test when nothing exists.
for file in $mask;do break;done if [[ -a $file ]] then echo "files exist matching $mask" else echo "no files exist matching $mask" fi
No processes.
> check if there is any file exist in /home/my_directory
if [ -z "`ls`" ] then echo "no files found." else echo "files found." fi
documented on: 04-20-99 15:37:59