7.2. 文件测试操作符

如果...返回真

-e

文件存在

-a

文件存在

这与 -e 的效果相同。它已被 “弃用”[1] 并且不鼓励使用。

-f

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

-s

文件大小不为零

-d

文件是一个目录

-b

文件是一个 块设备

-c

文件是一个 字符设备

device0="/dev/sda2"    # /   (root directory)
if [ -b "$device0" ]
then
  echo "$device0 is a block device."
fi

# /dev/sda2 is a block device.



device1="/dev/ttyS1"   # PCMCIA modem card.
if [ -c "$device1" ]
then
  echo "$device1 is a character device."
fi

# /dev/ttyS1 is a character device.

-p

文件是一个 管道

function show_input_type()
{
   [ -p /dev/fd/0 ] && echo PIPE || echo STDIN
}

show_input_type "Input"                           # STDIN
echo "Input" | show_input_type                    # PIPE

# This example courtesy of Carl Anderson.

-h

文件是一个 符号链接

-L

文件是一个符号链接

-S

文件是一个 套接字

-t

文件(描述符)与终端设备关联

此测试选项可用于检查是否stdin [ -t 0 ]stdout [ -t 1 ]在给定脚本中是终端。

-r

文件具有读取权限(对于运行测试的用户

-w

文件具有写入权限(对于运行测试的用户)

-x

文件具有执行权限(对于运行测试的用户)

-g

在文件或目录上设置了 set-group-id (sgid) 标志

如果目录具有sgid标志设置,则在该目录中创建的文件属于拥有该目录的组,而不一定属于创建该文件的用户的组。这对于工作组共享的目录可能很有用。

-u

在文件上设置了 set-user-id (suid) 标志

root 拥有的二进制文件,带有set-user-id标志设置后,即使普通用户调用它,也以 root 权限运行。[2] 这对于需要访问系统硬件的可执行文件(例如 pppdcdrecord)很有用。 如果缺少 suid 标志,则 非 root 用户将无法调用这些二进制文件。

	      -rwsr-xr-t    1 root       178236 Oct  2  2000 /usr/sbin/pppd
	      

带有suid标志设置的文件在其权限中显示 s

-k

粘滞位设置

通常称为粘滞位save-text-mode 标志是一种特殊类型的文件权限。 如果文件设置了此标志,则该文件将保留在缓存存储器中,以便更快地访问。[3] 如果在目录上设置,则它会限制写入权限。 设置粘滞位会在文件或目录列表中添加 t 到权限。 这将目录中特定文件的更改或删除限制为这些文件的所有者。

	      drwxrwxrwt    7 root         1024 May 19 21:26 tmp/
	      

如果用户不拥有设置了粘滞位的目录,但在该目录中具有写入权限,则她只能删除她在其中拥有的那些文件。 这可以防止用户在公共访问的目录(例如/tmp. (当然,目录的所有者root 可以删除或重命名那里的文件。)

-O

你是文件的所有者

-G

文件的组 ID 与你的相同

-N

文件自上次读取后被修改过

f1 -nt f2

文件f1比...新f2

f1 -ot f2

文件f1比...旧f2

f1 -ef f2

文件f1f2是同一个文件的硬链接

!

“非”——颠倒上述测试的意义(如果条件不存在则返回真)。

示例 7-4. 测试断开的链接

#!/bin/bash
# broken-link.sh
# Written by Lee bigelow <ligelowbee@yahoo.com>
# Used in ABS Guide with permission.

#  A pure shell script to find dead symlinks and output them quoted
#+ so they can be fed to xargs and dealt with :)
#+ eg. sh broken-link.sh /somedir /someotherdir|xargs rm
#
#  This, however, is a better method:
#
#  find "somedir" -type l -print0|\
#  xargs -r0 file|\
#  grep "broken symbolic"|
#  sed -e 's/^\|: *broken symbolic.*$/"/g'
#
#+ but that wouldn't be pure Bash, now would it.
#  Caution: beware the /proc file system and any circular links!
################################################################


#  If no args are passed to the script set directories-to-search 
#+ to current directory.  Otherwise set the directories-to-search 
#+ to the args passed.
######################

[ $# -eq 0 ] && directorys=`pwd` || directorys=$@


#  Setup the function linkchk to check the directory it is passed 
#+ for files that are links and don't exist, then print them quoted.
#  If one of the elements in the directory is a subdirectory then 
#+ send that subdirectory to the linkcheck function.
##########

linkchk () {
    for element in $1/*; do
      [ -h "$element" -a ! -e "$element" ] && echo \"$element\"
      [ -d "$element" ] && linkchk $element
    # Of course, '-h' tests for symbolic link, '-d' for directory.
    done
}

#  Send each arg that was passed to the script to the linkchk() function
#+ if it is a valid directoy.  If not, then print the error message
#+ and usage info.
##################
for directory in $directorys; do
    if [ -d $directory ]
	then linkchk $directory
	else 
	    echo "$directory is not a directory"
	    echo "Usage: $0 dir1 dir2 ..."
    fi
done

exit $?

示例 31-1示例 11-8示例 11-3示例 31-3示例 A-1 也说明了文件测试操作符的用法。

注释

[1]

根据 1913 年版的 韦氏词典

Deprecate
...

To pray against, as an evil;
to seek to avert by prayer;
to desire the removal of;
to seek deliverance from;
to express deep regret for;
to disapprove of strongly.

[2]

请注意,suid 二进制文件可能会打开安全漏洞。suid 标志对 shell 脚本无效。

[3]

在 Linux 系统上,粘滞位不再用于文件,仅用于目录。