Understanding some conditional expressions for the Korn shell or POSIX shell


Read more about POSIX shell on wikipedia. Below are the set of commands to understand some of the expressions for writing portable shell scripts. Empty cells in the "Example" column is for you to practice.

Exit Status for the "test" command:
0 - The Expression parameter is true.
1 - The Expression parameter is false or missing.
>1 - An error occurred.

SyntaxDescriptionExample
-a FileTrue, if the specified file is a symbolic link that points to another file that does exist.# touch file1
# ln -s file1 linktofile1
# ls -al linktofile1
# test -a linktofile1
# echo $?
0
# rm -f file1
# test -a linktofile1
# echo $?
1
-b FileTrue, if the specified file exists and is a block special file.All files in /dev are special files... they represent devices of the computer. (http://www.lanana.org/docs/device-list/devices-2.6+.txt)
# test -b /dev/ram0
# echo $?
0
-c FileTrue, if the specified file exists and is a character special file.All files in /dev are special files... they represent devices of the computer. (http://www.lanana.org/docs/device-list/devices-2.6+.txt)
# test -c /dev/mem0
# echo $?
0
-d FileTrue, if the specified file exists and is a directory.# mkdir abc
# test -d abc ; echo $?
-e FileTrue, if the specified file exists.# touch file1 ; test -e file1 ; echo $?
-f FileTrue, if the specified file exists and is an ordinary file. # touch file1 ; test -e file1 ; echo $?
-g FileTrue, if the specified file exists and its setgid bit is set.setgid is similar to setuid, with only diff that it will use a 2 instead of 4. (chmod 2XXX file instead of chmod 4XXX file) 
Read more: setgid and setuid

Negative test:
# touch file1 ; chmod 4000 file1 ; test -g file1 ; echo $?
Positive test:
# touch file1 ; chmod 2000 file1 ; test -g file1 ; echo $?
-h FileTrue, if the specified file exists and is a symbolic link.#  test -h linktofile1 ; echo $?
-k FileTrue, if the specified file exists and its sticky bit is set.# test -k file1 ; echo $?
1
# chmod +t file1
# test -k file1 ; echo $?
0
-n StringTrue, if the length of the specified string is nonzero.# str=
# test -n "$str" ; echo $?
1
# str="abc"
# test -n "$str" ; echo $?
0
-o OptionTrue, if the specified option is on.
-p FileTrue, if the specified file exists and is a FIFO special file or a named pipe. (A named pipe can be used to transfer information from one application to another without the use of an intermediate temporary file. Also two separate processes can access the pipe by name — one process can open it as a reader, and the other as a writer.)# mkfifo pcclm
# test -p pcclm ; echo $?
-r FileTrue, if the specified file exists and is readable by the current process.# touch myfile
# su <anotheruser>
# test -r /root/myfile
-s FileTrue, if the specified file exists and has a size greater than 0.# test -s /root/myfile ; echo $?
1
# echo "hello" >>/root/myfile
# test -s /root/myfile ; echo $?
0
-t FileDescriptorTrue, if specified file descriptor number is open and associated with a terminal device.
-u FileTrue, if the specified file exists and its setuid bit is set.
-w FileTrue, if the specified file exists and the write bit is on. However, the file will not be writable on a read-only file system even if this test indicates true.
-x FileTrue, if the specified file exists and the execute flag is on. If the specified file exists and is a directory, then the current process has permission to search in the directory.
-z StringTrue, if length of the specified string is 0. # mystr=""
# test -z "$mystr"
-L FileTrue, if the specified file exists and is a symbolic link.
-O FileTrue, if the specified file exists and is owned by the effective user ID of this process.
-G FileTrue, if the specified file exists and its group matches the effective group ID of this process.
-S FileTrue, if the specified file exists and is a socket.
File1 -nt File2True, if File1 exists and is newer than File2.
File1 -ot File2True, if File1 exists and is older than File2.
File1 -ef File2True, if File1 and File2 exist and refer to the same file.
String1 = String2True, if String1 is equal to String2.# test "a" = "a" ; echo $?
String1 != String2True, if String1 is not equal to String2. # test "a" != "b" ; echo $?
String = PatternTrue, if the specified string matches the specified pattern.
String != PatternTrue, if the specified string does not match the specified pattern.
String1 < String2True, if String1 comes before String2 based on the ASCII value of their characters.
String1 > String2True, if String1 comes after String2 based on the ASCII value of their characters.
Expression1 -eq Expression2True, if Expression1 is equal to Expression2.# test 2 -eq 2 ; echo $?
Expression1 -ne Expression2True, if Expression1 is not equal to Expression2.
Expression1 -lt Expression2True, if Expression1 is less than Expression2.
Expression1 -gt Expression2True, if Expression1 is greater than Expression2.
Expression1 -le Expression2True, if Expression1 is less than or equal to Expression2.
Expression1 -ge Expression2True, if Expression1 is greater than or equal to Expression2.
+