8.3 判断式

本实验手册介绍了Linux中的test命令和方括号[]用于文件检测和条件判断的基本用法,包括检测文件是否存在、类型和权限,并通过脚本示例展示了如何结合逻辑运算符和特殊变量编写实用的文件检测和参数处理脚本。

test命令
test命令(也可以写作 [ ] )是Linux中用于检查文件属性和比较值的基本命令,常用于Shell脚本中进行条件测试,如检测文件是否存在(-e)、是否是目录(-d)、是否可读(-r)等,以及进行字符串或数值的比较。

在开始之前,让我们先创建一个测试文件:

bash

# 创建示例文件
touch /root/sample.txt

首先我们来检测文件是否存在:

bash

test -e /root/sample.txt

你会发现命令执行后没有任何输出。这是因为test命令只返回执行结果,但不显示任何信息。我们可以通过特殊变量 $? 来查看命令的返回值:

bash

echo $?

返回值说明
  • 0 表示命令执行成功(条件为真)
  • 非0 表示命令执行失败(条件为假)

接下来测试一个不存在的文件:

bash

test -e /root/abc
echo $?

这次返回1,说明文件不存在。通过这种方式,我们就能判断文件是否存在了。

刚才的方法不够直观,我们可以结合 &&|| 运算符来改进:

bash

test -e /root/sample.txt && echo "文件存在" || echo "文件不存在"

这行命令的逻辑是:

  • 如果test命令返回0(文件存在),则执行 && 后的命令
  • 如果test命令返回非0(文件不存在),则执行 || 后的命令

1、创建以下文件用于测试:

bash

# 创建普通文件
touch testfile

# 创建目录
mkdir testdir

# 创建无权限文件
touch nopermission
chmod 000 nopermission

2、尝试使用不同的test参数检测这些文件:

bash

# 检测是否为目录
test -d testdir && echo "是目录"

# 检测是否为普通文件
test -f testfile && echo "是普通文件"

# 检测文件权限
test -r nopermission && echo "可读" || echo "不可读"
test -w nopermission && echo "可写" || echo "不可写"
test -x nopermission && echo "可执行" || echo "不可执行"

test 支持各种检测,以下是常用参数:

  • -e exist 只检查是否存在(非常常用)
  • -f file 检查是否存在且为普通文件(非常常用)
  • -d directory 检查是否存在且为目录
  • -c character 检查是否存在且为字符设备
  • -b block 检查是否存在且为块设备
  • -S socket 检查是否为Socket文件
  • -p pile 检查是否为管道文件
  • -r read 检查是否有读权限
  • -w write 检查是否有写权限
  • -x execute 检查是否有执行权限
  • -z 字符串长度是否为0
任务目的
本任务将帮助你编写一个实用的文件检测脚本。这个脚本可以检查文件的存在性、类型和权限,是test命令应用的一个很好例子。

脚本功能:

  1. 让用户输入一个文件名,如果这个文件不存在,给出提示;
  2. 如果存在,判断文件是普通文件还是目录,并给出提示;
  3. 继续判断权限

1、首先创建脚本文件:

bash

vim test.sh

文件内容为:

bash

#!/bin/bash
# Program: test.sh

# 使用read命令获取用户输入,-p参数用于显示提示信息
read -p "请输入文件名:"   filename

# 检查是否输入为空(-z 测试字符串长度是否为0)
test -z $filename && echo "必须输入一个文件名!" && exit 0

# 检查文件是否存在(! 表示取反,即不存在)
test ! -e $filename && echo "文件 $filename 不存在" && exit 0

# 判断文件类型
test -f $filename && filetype="普通文件"
test -d $filename && filetype="目录"

# 判断文件权限
test -r $filename && perm="可读"
test -w $filename && perm="$perm 可写"
test -x $filename && perm="$perm 可执行"

# 输出结果
echo "文件 $filename 的类型是 $filetype"
echo "文件的权限是 $perm"

1、给脚本添加执行权限:

bash

chmod +x test.sh

2、创建测试文件;

bash

# 创建普通文件
touch testfile
chmod 644 testfile

# 创建目录
mkdir testdir
chmod 755 testdir

# 创建无权限文件
touch noPermission
chmod 000 noPermission

3、测试不同情况

bash

# 测试普通文件
./test.sh
# 输入:testfile

# 测试目录
./test.sh
# 输入:testdir

# 测试无权限文件
./test.sh
# 输入:noPermission

# 测试不存在的文件
./test.sh
# 输入:notexist

思考
noPermission 文件的权限是可读可写,为什么?
关键点解释
  1. test -z $filename:检查输入是否为空
  2. test ! -e $filename:检查文件是否不存在
  3. && 运算符:前面命令成功才执行后面的命令
  4. $perm 变量:通过不断追加构建权限字符串
任务目的
在Shell脚本中,方括号[]是test命令的另一种形式,使用起来更加直观。本任务将帮助你掌握方括号的正确使用方法。

先看一个简单的例子:

bash

# 判断HOME变量是否为空
[ -z $HOME ]; echo $?

# 判断HOME变量是否等于/root
[ "$HOME" = "/root" ]; echo $?

重要规则
  • 方括号两端必须有空格
  • 方括号内的操作符两端也必须有空格
  • 变量最好用双引号括起来

bash

# 正确的写法
[ "$HOME" = "/root" ]

# 错误的写法
[$HOME="/root"]  # 没有空格
[ $HOME="/root" ]  # 等号周围没有空格

常用判断符号:

bash

# 字符串比较
[ "$str1" = "$str2" ]   # 相等
[ "$str1" != "$str2" ]  # 不相等

# 数字比较
[ "$num1" -eq "$num2" ]  # 等于.   equal
[ "$num1" -ne "$num2" ]  # 不等于. not equal
[ "$num1" -gt "$num2" ]  # 大于.   greater than
[ "$num1" -lt "$num2" ]  # 小于.   less than

# 逻辑运算
[ condition1 -a condition2 ]  # 与(and)
[ condition1 -o condition2 ]  # 或(or)

让我们来编写一个交互式脚本,演示方括号的使用。

脚本功能
  1. 程序运行后,提示用户输入Y或者N
  2. 如果用户输入Y或y,显示“程序继续运行”
  3. 如果用户输入N或n,显示“程序停止”
  4. 如果用户输入其他内容,提示“未知选项”

1、创建脚本文件:

bash

vim continue.sh

脚本内容如下:

bash

#!/bin/bash
# Program: continue.sh

# 提示用户输入
read -p "请输入Y继续程序或输入N停止程序:" yorn

# 判断输入是否为Y/y
[ "${yorn}" == "Y" -o "${yorn}" == "y" ] && echo "程序继续运行" && exit 0

# 判断输入是否为N/n
[ "${yorn}" == "N" -o "${yorn}" == "n" ] && echo "程序停止" && exit 0

# 如果都不是,显示未知选项
echo "未知选项" && exit 0

2、给脚本添加执行权限:

bash

chmod +x continue.sh

运行脚本:

命令可以带有选项和参数,例如 ls -la 查看包含隐藏文件在内的详细文件信息,脚本也可以带有参数。

在Shell脚本中,有以下重要的特殊变量:

特殊变量
  1. 位置参数:
    • $0: 脚本名称
    • $1: 第一个参数
    • $2: 第二个参数
    • 以此类推…
  2. 参数相关特殊变量:
    • $#: 参数的个数
    • $@: 所有参数(每个参数作为独立的字符串)
    • $*: 所有参数(作为单个字符串,参数间用空格分隔)

1、创建脚本文件:

bash

vim script.sh

脚本内容如下:

bash

#!/bin/bash
# Program: script.sh
# 返回值:1 - 参数个数异常

# 显示脚本名称
echo "脚本名是:$0"

# 显示参数个数
echo "参数个数:$#"

# 如果参数个数大于2,则退出
[ "$#" -gt 2 ] && echo "参数个数大于2,退出..." && exit 1

# 显示所有参数(两种方式)
echo "所有参数:$@"
echo "所有参数:$*"

# 显示个别参数
echo "第一个参数:$1"
echo "第二个参数:$2"

添加执行权限:

bash

chmod +x script.sh

测试不同运行方式:

bash

# 不带参数运行
./script.sh

# 带一个参数运行
./script.sh hello

# 带两个参数运行
./script.sh hello world

# 带三个参数运行
./script.sh apple banana orange

# 使用绝对路径运行
/root/scripts/script.sh hello world

# 使用source命令运行
source script.sh hello world

运行结果:

在Shell脚本中,shift命令用于移动位置参数。这个概念可能有点抽象,让我们通过一个生活中的例子来理解:

想象一下排队买票的场景:

  • 最开始有5个人排队:小明、小红、小张、小李、小王
  • 第一个人(小明)买完票离开后,队伍向前移动一位
  • 后面如果有3个人(小红、小张、小李)一起买团体票离开,剩下的人再向前移动

这就和shift命令的工作方式很像!

bash

#!/bin/bash
# 脚本名:shift_paramters.sh

echo "参数个数: $#"
echo "所有参数:$@"

# 偏移一个参数
shift
echo -e "\n偏移一个参数"
echo "参数个数: $#"
echo "所有参数:$@"

# 偏移3个参数
shift 3
echo -e "\n偏移三个参数"
echo "参数个数: $#"
echo "所有参数:$@"

运行结果及解析:

text

[root@RHEL7-1 scripts]# sh shift_paramters.sh 1 2 3 4 5
参数个数: 5            # 开始时有5个参数
所有参数:1 2 3 4 5     # 所有参数依次是1,2,3,4,5

偏移一个参数           # 执行shift后
参数个数: 4           # 参数数量减少到4个
所有参数:2 3 4 5      # 原来的第一个参数(1)被移除

偏移三个参数          # 执行shift 3后
参数个数: 1          # 参数数量减少到1个
所有参数:5           # 只剩下最后一个参数(5)

shift命令的作用:

  1. 移除最左边的参数
  2. 剩余参数向左移动
  3. 可以一次移动多个位置(如shift 3)
  4. 移动后原来的参数无法恢复
记住
shift是"移除并移动",而不是简单的"跳过"。一旦参数被shift掉,就无法再次访问了!

编写一个Shell脚本,实现以下功能:

  1. 接收一个文件名作为脚本参数(不是用read命令输入)
  2. 检查是否提供了参数,如果没有参数,显示"请提供文件名"并退出
  3. 检查参数数量是否大于2,如果是,显示“只提供一个参数”并退出
  4. 检查文件是否存在,如果不存在,显示"文件不存在"并退出
  5. 如果文件存在,显示该文件的读、写、执行权限状态

脚本文件名为:check_permission.sh

运行结果示例:

执行过程:

bash

# 创建测试文件
touch testfile
chmod 754 testfile

# 运行脚本
./check_permission.sh testfile
./check_permission.sh          # 不带参数
./check_permission.sh nofile   # 不存在的文件

观察:是否用双引号括起变量名会有什么不同(变量值为空时会有影响)

提交说明
提交运行脚本内容和运行截图。

相关内容