7.2. 文件测试操作符

如果下面的条件成立返回真...

-e

文件存在

-a

文件存在

这个和-e的作用一样. 它是不赞成使用的,所以它的用处不大。

-f

文件是一个普通文件(不是一个目录或是一个设备文件)

-s

文件大小不为零

-d

文件是一个目录

-b

文件是一个块设备(软盘, 光驱, 等等.)

-c

文件是一个字符设备(键盘, 调制解调器, 声卡, 等等.)

-p

文件是一个管道

-h

文件是一个符号链接

-L

文件是一个符号链接

-S

文件是一个socket

-t

文件(描述符)与一个终端设备相关

这个测试选项可以用于检查脚本中是否标准输入 ([ -t 0 ])或标准输出([ -t 1 ])是一个终端.

-r

文件是否可读 (指运行这个测试命令的用户的读权限)

-w

文件是否可写 (指运行这个测试命令的用户的读权限)

-x

文件是否可执行 (指运行这个测试命令的用户的读权限)

-g

文件或目录的设置-组-ID(sgid)标记被设置

如果一个目录的sgid标志被设置,在这个目录下创建的文件都属于拥有此目录的用户组,而不必是创建文件的用户所属的组。这个特性对在一个工作组里的同享目录很有用处。

-u

文件的设置-用户-ID(suid)标志被设置

一个root用户拥有的二进制执行文件如果设置了设置-用户-ID位(suid)标志普通用户可以以root权限运行。[1] 这对需要存取系统硬件的执行程序(比如说pppd和cdrecord)很有用。如果没有设置suid位,则这些二进制执行程序不能由非root的普通用户调用。
 	      -rwsr-xr-t    1 root       178236 Oct  2  2000 /usr/sbin/pppd
 	      
被设置了suid标志的文件在权限列中以s标志表示.

-k

粘住位设置

Commonly known as the "sticky bit," the save-text-mode flag is a special type of file permission. If a file has this flag set, that file will be kept in cache memory, for quicker access. [2] If set on a directory, it restricts write permission. Setting the sticky bit adds a t to the permissions on the file or directory listing.
 	      drwxrwxrwt    7 root         1024 May 19 21:26 tmp/
 	      
If a user does not own a directory that has the sticky bit set, but has write permission in that directory, he can only delete files in it that he owns. This keeps users from inadvertently overwriting or deleting each other's files in a publicly accessible directory, such as /tmp.

-O

你是文件拥有者

-G

你所在组和文件的group-id相同

-N

文件最后一次读后被修改

f1 -nt f2

文件f1f2

f1 -ot f2

文件f1f2

f1 -ef f2

文件f1f2 是相同文件的硬链接

!

"非" -- 反转上面所有测试的结果(如果没有给出条件则返回真).


例子 7-4. 测试断掉的连接

   1 #!/bin/bash
   2 # broken-link.sh
   3 # 由Lee bigelow所写<ligelowbee@yahoo.com>
   4 # 已经征得作者的同意.
   5 
   6 #一个用于发现死符号链接并且输出它们的链接文件的纯shell的脚本。
   7 #所以它们能把输出提供给xargs并处理 :)
   8 #例如: broken-link.sh /somedir /someotherdir|xargs rm
   9 #
  10 #下面是更好的发现死符号链接的办法:
  11 #
  12 #find "somedir" -type l -print0|\
  13 #xargs -r0 file|\
  14 #grep "broken symbolic"|
  15 #sed -e 's/^\|: *broken symbolic.*$/"/g'
  16 #
  17 #但这不是纯bash脚本,下面的则是.
  18 #注意: 谨防在/proc文件系统和死循环链接中使用!
  19 ##############################################################
  20 
  21 
  22 #如果没有参数被传递给脚本作为搜索目录,则使用当前目录
  23 #
  24 #
  25 ####################
  26 [ $# -eq 0 ] && directorys=`pwd` || directorys=$@
  27 
  28 #Setup the function linkchk to check the directory it is passed 
  29 #for files that are links and don't exist, then print them quoted.
  30 #If one of the elements in the directory is a subdirectory then 
  31 #send that send that subdirectory to the linkcheck function.
  32 ##########
  33 linkchk () {
  34     for element in $1/*; do
  35     [ -h "$element" -a ! -e "$element" ] && echo \"$element\"
  36     [ -d "$element" ] && linkchk $element
  37     # Of course, '-h' tests for symbolic link, '-d' for directory.
  38     done
  39 }
  40 
  41 #Send each arg that was passed to the script to the linkchk function
  42 #if it is a valid directoy.  If not, then print the error message
  43 #and usage info.
  44 ################
  45 for directory in $directorys; do
  46     if [ -d $directory ]
  47 	then linkchk $directory
  48 	else 
  49 	    echo "$directory is not a directory"
  50 	    echo "Usage: $0 dir1 dir2 ..."
  51     fi
  52 done
  53 
  54 exit 0

例子 28-1, 例子 10-7, 例子 10-3, 例子 28-3, 和 例子 A-1 也说明了文件测试操作符的用法.

[1]

一定要意识到suid二进制文件可能引起潜在的安全漏洞,并且在shell脚本中suid标志已经不起作用了。

[2]

在现代UNIX操作系统,粘住位已经不在文件中再使用,只用在目录中。