Linux shell编程学习笔记13:文件测试运算

*更新记录:20231020 为补充了(十五)检测文件是否存在并且是一个符号链接 补充了一个例子

Linux Shell 脚本编程和其他编程语言一样,支持算数、关系、布尔、逻辑、字符串、文件测试等多种运算。前面几节我们依次研究了 Linux shell编程 中的 字符串运算、算术运算、关系运算、布尔运算 和 逻辑运算,今天我们来研究 Linux shell编程中的文件测试运算。

一、文件测试运算符说明

操作符 说明 备注
-b file 检测文件是否是块设备文件,如果是,则返回 true。 block
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 char
-d file 检测文件是否是目录,如果是目录,则返回 true。 directory
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 file
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 set Group ID
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。
-p file 检测文件是否是有名管道,如果是,则返回 true。 name pipe
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 Set User ID
-r file 检测文件是否可读,如果是,则返回 true。 readonly
-w file 检测文件是否可写,如果是,则返回 true。 writeable
-x file 检测文件是否可执行,如果是,则返回 true。 excecutable
-s file 检测文件是否不为空(文件大小是否大于0),不为空返回 true。 space
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 exist
-S file 检测文件是否 socket socket
-L file 检测文件是否存在并且是一个符号链接 link

二、文件测试运算实例

为了进行文件测试实例演示,我们使用文件 /init 和 根目录 / 来作为操作对象。

我们先用ls -l 命令查看文件 /init 的详细属性:

user @ host: / $ ++ls -l init++

-rwxr-xr-x 1 root root 492 Apr 12 2023 init

user @ host : / $

ls -l 命令返回信息中的第一列共有10个字符,可以分为两个部分:

第一个部分是文件类型,由第1个字符表示,它可能是下列值之一:

  • :表示普通文件

d :表示目录

l :表示符号链接

c :表示字符设备文件

b :表示块设备文件

s :表示套接字文件

p :表示管道文件

第二部分表示访问权限,包括第2-第10个字符,以3个字符为一组,共分为3组,第一组由前三个字符组成,表示所有者的权限,第二组由中间三个字符组成,表示所属组的权限,第三组由最后三个字符,表示其他用户的权限。每个字符的含义如下:

r :表示读取权限

w :表示写入权限

x :表示执行权限

  • :表示没有对应权限

由命令返回结果可以看出,/init 是一个文件,文件所有者具有读取(r)写入(w)执行(x)权限,所属组和其他用户具有读取(r)和执行(x)权限。

我们再用ls -ld 命令查看 / 的详细属性:

user @ host : / $ ++ls -ld /++

drwxr-xr-x 17 root root 380 Apr 12 2023 //

由命令返回结果可以看出,/是一个目录,目录所有者具有读取(r)写入(w)执行(x)权限,所属组和其他用户具有读取(r)和执行(x)权限。

(一)检测文件是否是块设备文件

user @ host : / $ ++f="/init"++

user @ host : / ++if\[-b f ]; then echo "f is a block file"; else echo "f is not a block file"; fi++

/init is not a block file

user @ host : / $

可见 /init 不是块设备文件

(二)检测文件是否是字符设备文件

user @ host : / $ ++f="/init"++

user @ host : / ++if \[-c f]; then echo "f is a character file"; else echo "f is not a character filel"; fi++

/init is not a character file

user @ host : / $

可见 /init 不是字符设备文件。

(三)检测文件是否是目录

user @ host : / $ ++f="/init"++

user @ host : / ++if \[-d f ]; then echo"f is a directory"; else echo "f is not a directory"; fi++

/init is not a directory

user @ host : / $

可见/init 不是一个目录而是一个文件。

user @ host : / $ ++f="//"++

user @ host : / i++f \[ -d f ];then echo "f is a directory"; else echo "f is not a directory";fi++

// is a directory

user @ host : / $ f="/"

user @ host : / if \[ -d f ]; then echo "f is a directory"; else echo "f is not a directory"; fi

/ is a directory

user @ host : / $

可见,/ 是一个目录,而不是文件。

(四)检测文件是否是普通文件

user @ host : / $ ++f="/init"++

user @ host : / ++if \[-f f ]; then echo"f is a file"; else echo "f is not a file"; fi++

/init is a file

user @ host : / $ ++f="/"++

user @ host : / ++if \[ -d f ]; then echo "f is a file"; else echo "f is not a file"; fi++

/ is not a fle

user @ host : / $

可见,/init是一个文件,/ 不是一个文件。

(五)检测文件是否设置了 SGID 位

user @ host : / $ ++f="/init"++

user @ host : / ++if \[ -g f ];then echo "f has set the SGID"; else echo "f has not set the SGID "; fi++

/init has not set the SGID

user @ host : / $ ++f="/"++

user @ host : / ++if \[ -g f ];then echo "f has set the SGID"; else echo "f has not set the SGID "; fi++

/ has not set the SGID

user @ host : / $

可见 /init 和 / 都没有设置SGID。

(六)检测文件是否设置了粘着位(Sticky Bit)

user @ host : / $ ++f="/init"++

user @ host : / ++ if \[ -k f ];then echo "f has set the Sticky Bit"; else echo "f has not set the Sticky Bit"; fi++

/init has not set the Sticky Bit

user @ host : / $ ++f="/"++

user @ host : / ++if \[ -k f ];then echo "f has set the Sticky Bit"; else echo "f has not set the Sticky Bit"; fi++

/ has not set the Sticky Bit

user @ host : / $

可见 /init 和 / 都没有设置粘着位(Sticky Bit)

(七)检测文件是否是有名管道

user @ host : / $ ++f="/init"++

user @ host : / ++if \[ -p f ];then echo "f is a named pipe "; else echo "f is not a named pipe"; fi++

/init is not a named pipe

user @ host : / $ ++f="/"++

user @ host : / ++if \[ -p f ];then echo "f is a named pipe "; else echo "f is not a named pipe"; fi++

/ is not a named pipe

user @ host : / $

可见 /init 和 / 都不是有名管道。

(八)检测文件是否设置了 SUID 位

user @ host : / $ ++f="/init"++

user @ host : / if \[ -u f ];then echo "f has set the SUID"; else echo "f has not set the SUID"; fi

/init has not set the SUID

user @ host : / $ ++f="/"++

user @ host : / ++if \[ -u f ];then echo "f has set the SUID"; else echo "f has not set the SUID"; fi++

/ is has not set the SUID

user @ host : / $

可见 /init 和 / 都没有设置 SUID 位

(九)检测文件是否可读

user @ host : / $ ++f="/init"++

user @ host : / ++if \[ -r f ]; then echo "f is readable"; else echo "f is not readable"; fi++

/init is readable

user@host:/ $

可见 /init是可以读取的。

(十)检测文件是否可写

user @ host : / $ f="/ init"

user @ host : / if \[ -w f ];then echo "f is writable"; else echo "f is not writable"; fi

/init is not writable

user @ host : / $ f="/"

user @ host : / if \[ -w f ];then echo "f is writable"; else echo "f is not writable"; fi

/ is not writable

user @ host : / $

可见 /init 和 / 都不可写入。

(十一)检测文件是否可执行

user @ host : / $ f="/init"

user @ host : / if \[ -x f ];then echo "f is executable"; else echo "f is not executable"; fi

/init is executable

user @ host : / $ f="/"

user @ host : / if \[ -x f ];then echo "f is executable"; else echo "f is not executable"; fi

/ is executable

user @ host : / $

可见 /init 和 / 都可以执行。

(十二)检测文件是否不为空(文件大小是否大于0)

user @ host : / $ ++f="/init"++

user @ host : / ++if \[ -s f ];then echo "f is not space"; else echo "f is space"; fi++

/init is not space

可见 /init 不为空。

我们可以用cat命令查看 /init的内容:

(十三)检测文件(包括目录)是否存在

user @ host : / $ ++f="/init"++

user @ host : / ++if \[ -e f ];then echo "f exists"; else echo "f does not exist"; fi++

/init exists

user @ host : / $ ++f="/"++

user @ host : / ++if \[ -e f ];then echo "f exists"; else echo "f does not exist"; fi++

/ exists

user @ host : / ++if \[ -e null \];then echo "f exists"; else echo "$f does not exist"; fi++

/ exists

user @ host : / ++if \[ -e nil \];then echo "f exists"; else echo "$f does not exist"; fi++

/ exists

user @ host : / ++if \[ -e /dev/null \];then echo "f exists"; else echo "$f does not exist"; fi++

/ exists

user @ host : / $ ++f="/dev/null"++

user @ host : / if \[ -e f ];then echo "f exists"; else echo "f does not exist"; fi

/dev/null exists

可见 /init 和 / 以及 /dev/null 都存在。

(十四)检测文件是否 socket

user @ host : / $ ++f="/init"++

user @ host : / ++if \[ -S f ];then echo "f is a socket"; else echo "f is not a socket"; fi++

/init is not a socket

user @ host : / $ ++f="/"++

user @ host : / ++if \[ -S f ];then echo "f is a socket"; else echo "f is not a socket"; fi++

/ is not a socket

(十五)检测文件是否存在并且是一个符号链接

user @ host : / $ ++f="/init"++

user @ host : / ++if \[ -L f ];then echo "f is a link"; else echo "f is not a link"; fi++

/init is not a link

user @ host : / $ ++f="/"++

user @ host : / ++if \[ -L f ];then echo "f is a link"; else echo "f is not a link"; fi++

/ is not a link

user @ host : ~ $ ++ls -l /dev/stdout++

lrwxrwxrwx 1 root root 15 10月 20 2023 /dev/stdout -> /proc/self/fd/1

user @ host : ~ $

/dev/stdout 是Linux 系统中一个特殊的符号链接文件,指向当前进程的标准输出文件描述符,代表标准输出。

相关推荐
Konwledging18 分钟前
kernel-devel_kernel-headers_libmodules
linux
Web极客码19 分钟前
CentOS 7.x如何快速升级到CentOS 7.9
linux·运维·centos
一位赵40 分钟前
小练2 选择题
linux·运维·windows
代码游侠1 小时前
学习笔记——Linux字符设备驱动开发
linux·arm开发·驱动开发·单片机·嵌入式硬件·学习·算法
Lw老王要学习2 小时前
CentOS 7.9达梦数据库安装全流程解析
linux·运维·数据库·centos·达梦
CRUD酱2 小时前
CentOS的yum仓库失效问题解决(换镜像源)
linux·运维·服务器·centos
zly35002 小时前
VMware vCenter Converter Standalone 转换Linux系统,出现两个磁盘的处理
linux·运维·服务器
Albert Edison3 小时前
【Python】函数
java·linux·python·pip
General_G3 小时前
Linux中的信号
linux·运维·服务器
诸神缄默不语3 小时前
当无法直接用apt instll时,Linux如何离线安装软件包(以make为例)
linux·运维·服务器