介绍
在本次实验中,你将学习如何使用 Linux 条件测试来自动化系统检查和验证。Linux 提供了强大的 test 命令,允许你评估条件并根据结果执行操作。理解如何使用此命令对于编写能够做出决策并响应不同条件的 shell 脚本至关重要。
在整个实验过程中,你将学习 test 命令的各个方面,包括文件测试、字符串比较和数值评估。在本次实验结束时,你将能够编写脚本,对系统执行自动化检查并帮助维护其完整性。
在本次实验中,你将学习如何使用 Linux 条件测试来自动化系统检查和验证。Linux 提供了强大的 test 命令,允许你评估条件并根据结果执行操作。理解如何使用此命令对于编写能够做出决策并响应不同条件的 shell 脚本至关重要。
在整个实验过程中,你将学习 test 命令的各个方面,包括文件测试、字符串比较和数值评估。在本次实验结束时,你将能够编写脚本,对系统执行自动化检查并帮助维护其完整性。
Linux 中的 test 命令是在 shell 脚本中评估条件的重要工具。它允许你检查文件属性、比较字符串、评估数值等等。当被测试的条件为真时,test 返回退出状态码 0;否则,返回非零退出状态码。
让我们从基础开始。首先,导航到你的项目目录:
cd ~/project
test 命令有两种写法:
test 关键字,后面紧跟条件[ ] 将条件括起来让我们尝试这两种方法来检查一个目录是否存在:
## 方法 1:使用 'test' 关键字
test -d ~/project && echo "The project directory exists."
## 方法 2:使用方括号
[ -d ~/project ] && echo "The project directory exists."
你应该会看到这两个命令都输出以下内容:
The project directory exists.
-d 选项用于检查目录是否存在。&& 运算符用于仅在测试条件为真时执行 echo 命令。
一些常见的文件测试选项包括:
-d file:如果文件存在且为目录,则为真-e file:如果文件存在,则为真-f file:如果文件存在且为普通文件,则为真-r file:如果文件存在且可读,则为真-w file:如果文件存在且可写,则为真-x file:如果文件存在且可执行,则为真-s file:如果文件存在且大小大于零,则为真让我们创建一个测试文件并检查其属性:
## 创建一个测试文件
echo "Hello, Linux condition testing!" > test_file.txt
## 检查文件是否存在
test -e test_file.txt && echo "The file exists."
## 检查文件是否可读
[ -r test_file.txt ] && echo "The file is readable."
## 检查文件是否为空
[ -s test_file.txt ] && echo "The file is not empty."
这些命令应该会产生以下输出:
The file exists.
The file is readable.
The file is not empty.
现在,让我们创建一个简单的 shell 脚本,使用 test 命令检查文件是否存在,如果不存在则创建它:
## 创建一个脚本文件
cat > check_file.sh << 'EOF'
#!/bin/bash
FILENAME="status.txt"
if [ ! -e "$FILENAME" ]; then
echo "File $FILENAME does not exist. Creating it now."
echo "This is a status file." > "$FILENAME"
else
echo "File $FILENAME already exists."
fi
## 显示文件内容
echo "Content of $FILENAME:"
cat "$FILENAME"
EOF
## 使脚本可执行
chmod +x check_file.sh
## 运行脚本
./check_file.sh
当你运行脚本时,你应该会看到类似于以下的输出:
File status.txt does not exist. Creating it now.
Content of status.txt:
This is a status file.
如果你再次运行脚本,你会看到:
File status.txt already exists.
Content of status.txt:
This is a status file.
这展示了如何使用 test 命令检查文件是否存在,并根据结果采取不同的操作。
在这一步中,你将学习如何使用 test 命令来比较字符串。当你需要验证用户输入、检查环境变量或根据文本内容做出决策时,这非常有用。
常见的字符串比较运算符包括:
==:等于!=:不等于-z:如果字符串为空,则为真-n:如果字符串不为空,则为真让我们从测试不同的字符串条件开始:
## 测试两个字符串是否相等
str1="linux"
str2="linux"
[ "$str1" == "$str2" ] && echo "The strings are equal."
## 测试两个字符串是否不同
str3="ubuntu"
[ "$str1" != "$str3" ] && echo "The strings are different."
## 测试字符串是否为空
empty_str=""
[ -z "$empty_str" ] && echo "The string is empty."
## 测试字符串是否不为空
[ -n "$str1" ] && echo "The string is not empty."
输出应该是:
The strings are equal.
The strings are different.
The string is empty.
The string is not empty.
现在,让我们创建一个脚本,要求输入密码并检查它是否符合某些标准:
## 创建一个密码验证脚本
cat > password_check.sh << 'EOF'
#!/bin/bash
echo "Enter a password:"
read -s password
## 检查密码是否为空
if [ -z "$password" ]; then
echo "Error: Password cannot be empty."
exit 1
fi
## 检查密码长度
if [ ${#password} -lt 8 ]; then
echo "Error: Password must be at least 8 characters long."
exit 1
fi
## 检查密码是否包含 "password" 这个词
if [[ "$password" == *password* ]]; then
echo "Error: Password cannot contain the word 'password'."
exit 1
fi
echo "Password is valid!"
EOF
## 使脚本可执行
chmod +x password_check.sh
## 运行脚本
echo "You can test the script by running: ./password_check.sh"
尝试使用不同的密码运行脚本,看看它如何验证输入:
## 用短密码进行测试
echo "short" | ./password_check.sh
## 用包含 "password" 的密码进行测试
echo "mypassword123" | ./password_check.sh
## 用有效密码进行测试
echo "SecurePass123" | ./password_check.sh
前两个测试应该失败,而第三个测试应该成功。
让我们创建另一个脚本,根据文本输入处理系统状态:
## 创建一个系统状态脚本
cat > system_status.sh << 'EOF'
#!/bin/bash
echo "Enter system status (normal, warning, critical):"
read status
if [ -z "$status" ]; then
echo "No status provided. Assuming normal operation."
status="normal"
fi
case "$status" in
"normal")
echo "System is operating normally. No action required."
;;
"warning")
echo "Warning: System requires attention. Check log files."
;;
"critical")
echo "CRITICAL: Immediate action required! System stability at risk."
;;
*)
echo "Unknown status: $status. Please use normal, warning, or critical."
;;
esac
EOF
## 使脚本可执行
chmod +x system_status.sh
## 运行脚本
echo "You can test the script by running: ./system_status.sh"
尝试使用不同的状态输入运行脚本:
## 用 "normal" 状态进行测试
echo "normal" | ./system_status.sh
## 用 "warning" 状态进行测试
echo "warning" | ./system_status.sh
## 用 "critical" 状态进行测试
echo "critical" | ./system_status.sh
## 用无效状态进行测试
echo "unstable" | ./system_status.sh
## 用空输入进行测试
echo "" | ./system_status.sh
每个输入都应该根据脚本中的条件逻辑产生不同的输出。
在这一步中,你将学习如何使用 test 命令进行数值比较。这对于检查资源使用情况、验证用户输入或根据数值做出决策非常有用。
常见的数值比较运算符包括:
-eq:等于-ne:不等于-lt:小于-le:小于或等于-gt:大于-ge:大于或等于让我们从一些基本的数值比较开始:
## 比较两个数字
num1=10
num2=20
## 等于
[ $num1 -eq 10 ] && echo "$num1 is equal to 10"
## 不等于
[ $num1 -ne $num2 ] && echo "$num1 is not equal to $num2"
## 小于
[ $num1 -lt $num2 ] && echo "$num1 is less than $num2"
## 大于
[ $num2 -gt $num1 ] && echo "$num2 is greater than $num1"
## 小于或等于
[ $num1 -le 10 ] && echo "$num1 is less than or equal to 10"
## 大于或等于
[ $num2 -ge 20 ] && echo "$num2 is greater than or equal to 20"
输出应该如下所示:
10 is equal to 10
10 is not equal to 20
10 is less than 20
20 is greater than 10
10 is less than or equal to 10
20 is greater than or equal to 20
现在,让我们创建一个脚本,用于检查磁盘空间,并在磁盘空间低于某个阈值时发出警报:
## 创建一个磁盘空间检查脚本
cat > disk_check.sh << 'EOF'
#!/bin/bash
## 获取磁盘使用百分比(去除 % 符号)
DISK_USAGE=$(df -h / | grep / | awk '{print $5}' | sed 's/%//')
## 设置阈值
WARNING_THRESHOLD=70
CRITICAL_THRESHOLD=90
echo "Current disk usage: $DISK_USAGE%"
if [ $DISK_USAGE -ge $CRITICAL_THRESHOLD ]; then
echo "CRITICAL: Disk usage is critically high!"
echo "Action: Clean up unnecessary files immediately."
elif [ $DISK_USAGE -ge $WARNING_THRESHOLD ]; then
echo "WARNING: Disk usage is getting high."
echo "Action: Consider cleaning up some files soon."
else
echo "OK: Disk usage is normal."
echo "No action required."
fi
EOF
## 使脚本可执行
chmod +x disk_check.sh
## 运行脚本
./disk_check.sh
该脚本将显示当前的磁盘使用情况,并根据磁盘的满度输出不同的消息。
让我们再创建一个模拟温度监测系统的脚本:
## 创建一个温度监测脚本
cat > temp_monitor.sh << 'EOF'
#!/bin/bash
## 生成 15 到 35 之间的随机温度的函数
generate_temp() {
echo $((RANDOM % 21 + 15))
}
## 生成随机温度
TEMP=$(generate_temp)
echo "Current temperature: ${TEMP}°C"
## 温度阈值
MIN_TEMP=18
MAX_TEMP=26
if [ $TEMP -lt $MIN_TEMP ]; then
echo "Action: Increase heating. Temperature is below minimum threshold."
elif [ $TEMP -gt $MAX_TEMP ]; then
echo "Action: Activate cooling. Temperature is above maximum threshold."
else
echo "Status: Temperature is within acceptable range."
fi
## 对极端温度进行额外检查
if [ $TEMP -ge 30 ]; then
echo "WARNING: Temperature is very high. Check cooling systems."
fi
if [ $TEMP -le 17 ]; then
echo "WARNING: Temperature is very low. Check heating systems."
fi
EOF
## 使脚本可执行
chmod +x temp_monitor.sh
## 运行脚本
./temp_monitor.sh
每次运行此脚本时,它都会生成一个随机温度并做出相应的响应。多次运行该脚本,观察不同的结果:
## 多次运行温度监测脚本
./temp_monitor.sh
./temp_monitor.sh
./temp_monitor.sh
这些示例展示了如何使用数值条件来监控系统参数,并根据阈值采取适当的行动。
在这一步中,你将学习如何使用逻辑运算符组合多个条件。这对于在脚本中创建复杂的决策逻辑至关重要。
三个主要的逻辑运算符是:
&&(逻辑与):如果两个条件都为真,则结果为真||(逻辑或):如果至少有一个条件为真,则结果为真!(逻辑非):如果条件为假,则结果为真让我们从一些基本示例开始:
## 创建一个测试文件
touch test_file.txt
chmod 644 test_file.txt
## 逻辑与运算符 - 两个条件都必须为真
[ -f test_file.txt ] && [ -r test_file.txt ] && echo "The file exists and is readable."
## 逻辑或运算符 - 至少有一个条件必须为真
[ -x test_file.txt ] || [ -w test_file.txt ] && echo "The file is either executable or writable."
## 逻辑非运算符 - 反转条件
[ ! -x test_file.txt ] && echo "The file is not executable."
## 组合多个运算符
[ -f test_file.txt ] && [ -r test_file.txt ] && [ ! -x test_file.txt ] && echo "The file exists, is readable, but is not executable."
你应该会看到类似以下的输出:
The file exists and is readable.
The file is either executable or writable.
The file is not executable.
The file exists, is readable, but is not executable.
test 命令还允许你在一组方括号内使用这些运算符组合条件:
-a(逻辑与)-o(逻辑或)例如:
## 在单个 test 命令中使用逻辑与
[ -f test_file.txt -a -r test_file.txt ] && echo "The file exists and is readable."
## 在单个 test 命令中使用逻辑或
[ -x test_file.txt -o -w test_file.txt ] && echo "The file is either executable or writable."
让我们创建一个更复杂的脚本,用于检查系统资源:
## 创建一个系统资源检查脚本
cat > resource_check.sh << 'EOF'
#!/bin/bash
echo "Checking system resources..."
## 检查内存使用情况
MEM_THRESHOLD=80
MEM_USED=$(free | grep Mem | awk '{print int($3/$2 * 100)}')
echo "Memory usage: ${MEM_USED}%"
## 检查磁盘空间
DISK_THRESHOLD=70
DISK_USED=$(df -h / | grep / | awk '{print $5}' | sed 's/%//')
echo "Disk usage: ${DISK_USED}%"
## 检查 CPU 负载(1 分钟平均)
LOAD_THRESHOLD=1.0
CPU_LOAD=$(cat /proc/loadavg | awk '{print $1}')
echo "CPU load average: ${CPU_LOAD}"
## 组合条件检查
if [ $MEM_USED -gt $MEM_THRESHOLD ] && [ $DISK_USED -gt $DISK_THRESHOLD ]; then
echo "CRITICAL: Both memory and disk usage are high!"
echo "Action: Free up resources immediately."
elif [ $MEM_USED -gt $MEM_THRESHOLD ] || [ $DISK_USED -gt $DISK_THRESHOLD ]; then
echo "WARNING: Either memory or disk usage is high."
echo "Action: Monitor system closely."
else
echo "OK: Memory and disk usage are within acceptable limits."
fi
## 在比较之前检查负载是否为数字
if [[ $CPU_LOAD =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
## 我们需要使用 bc 进行浮点数比较
if (( $(echo "$CPU_LOAD > $LOAD_THRESHOLD" | bc -l) )); then
echo "WARNING: CPU load is high. Check for resource-intensive processes."
else
echo "OK: CPU load is normal."
fi
else
echo "Error: Could not parse CPU load value."
fi
EOF
## 使脚本可执行
chmod +x resource_check.sh
## 运行脚本
./resource_check.sh
这个脚本会检查内存使用情况、磁盘空间和 CPU 负载,然后根据这些条件的组合提供不同的输出。
最后,让我们创建一个脚本,使用多个条件验证用户输入:
## 创建一个输入验证脚本
cat > validate_input.sh << 'EOF'
#!/bin/bash
echo "Enter a username (lowercase letters only, 3-8 characters):"
read username
echo "Enter your age (must be 18 or older):"
read age
## 用户名验证
is_valid_username=true
## 检查用户名是否为空
if [ -z "$username" ]; then
echo "Error: Username cannot be empty."
is_valid_username=false
fi
## 检查用户名长度
if [ ${#username} -lt 3 ] || [ ${#username} -gt 8 ]; then
echo "Error: Username must be between 3 and 8 characters."
is_valid_username=false
fi
## 检查用户名是否只包含小写字母
if [[ ! "$username" =~ ^[a-z]+$ ]]; then
echo "Error: Username must contain only lowercase letters."
is_valid_username=false
fi
## 年龄验证
is_valid_age=true
## 检查年龄是否为数字
if [[ ! "$age" =~ ^[0-9]+$ ]]; then
echo "Error: Age must be a number."
is_valid_age=false
fi
## 检查年龄是否至少为 18 岁
if [ "$is_valid_age" = true ] && [ $age -lt 18 ]; then
echo "Error: You must be at least 18 years old."
is_valid_age=false
fi
## 最终验证
if [ "$is_valid_username" = true ] && [ "$is_valid_age" = true ]; then
echo "Registration successful!"
echo "Welcome, $username. Your account has been created."
else
echo "Registration failed. Please correct the errors and try again."
fi
EOF
## 使脚本可执行
chmod +x validate_input.sh
## 运行脚本
echo "You can test the script by running: ./validate_input.sh"
尝试使用不同的输入运行脚本,看看组合条件如何共同验证用户输入:
## 使用有效输入进行测试
echo -e "john\n25" | ./validate_input.sh
## 使用无效用户名(太短)进行测试
echo -e "jo\n25" | ./validate_input.sh
## 使用无效用户名(包含大写字母)进行测试
echo -e "John\n25" | ./validate_input.sh
## 使用无效年龄(未满 18 岁)进行测试
echo -e "john\n17" | ./validate_input.sh
## 使用无效年龄(不是数字)进行测试
echo -e "john\nabc" | ./validate_input.sh
这些示例展示了如何组合多个条件,在脚本中创建复杂的验证逻辑。
在这最后一步,你将把所学的所有知识结合起来,创建一个全面的系统监控脚本。这个脚本将检查各种系统参数,并提供一份总结报告。
让我们创建一个监控系统多个方面的脚本:
## 创建一个系统监控脚本
cat > system_monitor.sh << 'EOF'
#!/bin/bash
echo "========================================"
echo " System Monitoring Report"
echo " $(date)"
echo "========================================"
echo
## 1. 检查重要的系统文件是否存在
echo "1. System Files Check:"
important_files=("/etc/passwd" "/etc/hosts" "/etc/resolv.conf")
all_files_exist=true
for file in "${important_files[@]}"; do
if [ -e "$file" ]; then
echo " [OK] $file exists"
## 检查文件是否为空
if [ ! -s "$file" ]; then
echo " [WARNING] $file is empty"
fi
## 检查文件是否可读
if [ ! -r "$file" ]; then
echo " [WARNING] $file is not readable"
fi
else
echo " [ERROR] $file does not exist"
all_files_exist=false
fi
done
if [ "$all_files_exist" = true ]; then
echo " All system files are present."
else
echo " Some system files are missing. Check the errors above."
fi
echo
## 2. 检查磁盘空间
echo "2. Disk Space Check:"
disk_usage=$(df -h / | grep / | awk '{print $5}' | sed 's/%//')
echo " Root partition usage: ${disk_usage}%"
if [ $disk_usage -ge 90 ]; then
echo " [CRITICAL] Disk usage is critically high!"
elif [ $disk_usage -ge 70 ]; then
echo " [WARNING] Disk usage is getting high."
else
echo " [OK] Disk usage is normal."
fi
echo
## 3. 检查内存使用情况
echo "3. Memory Usage Check:"
mem_total=$(free -m | grep Mem | awk '{print $2}')
mem_used=$(free -m | grep Mem | awk '{print $3}')
mem_percentage=$((mem_used * 100 / mem_total))
echo " Memory usage: ${mem_percentage}% (${mem_used}MB used out of ${mem_total}MB)"
if [ $mem_percentage -ge 90 ]; then
echo " [CRITICAL] Memory usage is critically high!"
elif [ $mem_percentage -ge 70 ]; then
echo " [WARNING] Memory usage is getting high."
else
echo " [OK] Memory usage is normal."
fi
echo
## 4. 检查活跃进程
echo "4. Process Check:"
critical_processes=("sshd" "cron")
for process in "${critical_processes[@]}"; do
if pgrep -x "$process" > /dev/null; then
echo " [OK] $process is running"
else
echo " [ERROR] $process is not running"
fi
done
echo
## 5. 检查系统负载
echo "5. System Load Check:"
load_1min=$(cat /proc/loadavg | awk '{print $1}')
load_5min=$(cat /proc/loadavg | awk '{print $2}')
load_15min=$(cat /proc/loadavg | awk '{print $3}')
echo " Load average: $load_1min (1 min), $load_5min (5 min), $load_15min (15 min)"
## 确定 CPU 核心数
num_cores=$(grep -c ^processor /proc/cpuinfo)
load_threshold=$(echo "scale=2; $num_cores * 0.7" | bc)
if (( $(echo "$load_1min > $load_threshold" | bc -l) )); then
echo " [WARNING] High load detected. The system might be under stress."
else
echo " [OK] System load is normal."
fi
echo
## 6. 检查最近的登录失败尝试
echo "6. Security Check:"
if [ -f /var/log/auth.log ]; then
failed_logins=$(grep "Failed password" /var/log/auth.log | wc -l)
echo " Failed login attempts: $failed_logins"
if [ $failed_logins -gt 10 ]; then
echo " [WARNING] High number of failed login attempts detected."
else
echo " [OK] Normal login activity."
fi
else
echo " [INFO] Cannot check login attempts (auth.log not accessible)"
fi
echo
## 7. 总结
echo "7. System Status Summary:"
critical_count=$(grep -c "\[CRITICAL\]" <<< "$(cat /dev/stdin)")
warning_count=$(grep -c "\[WARNING\]" <<< "$(cat /dev/stdin)")
error_count=$(grep -c "\[ERROR\]" <<< "$(cat /dev/stdin)")
if [ $critical_count -gt 0 ]; then
echo " [CRITICAL] System has critical issues that need immediate attention!"
elif [ $warning_count -gt 0 ] || [ $error_count -gt 0 ]; then
echo " [WARNING] System has some issues that should be addressed soon."
else
echo " [OK] System is operating normally. No significant issues detected."
fi
echo
echo "========================================"
echo " End of System Monitoring Report"
echo "========================================"
EOF
## 使脚本可执行
chmod +x system_monitor.sh
## 运行脚本
./system_monitor.sh
这个全面的脚本会执行以下检查:
输出会根据你系统的当前状态而有所不同,但它会提供系统健康状况的全面概述。
为了让这个脚本更有用,你可以:
让我们创建一个更简单的版本,你可以定期调度它运行:
## 创建一个简化的监控脚本用于定期调度
cat > daily_check.sh << 'EOF'
#!/bin/bash
## 设置日志文件
LOG_FILE="/tmp/system_check_$(date +%Y%m%d).log"
## 开始记录日志
echo "System Check: $(date)" > $LOG_FILE
echo "--------------------------------" >> $LOG_FILE
## 检查磁盘空间
disk_usage=$(df -h / | grep / | awk '{print $5}' | sed 's/%//')
echo "Disk usage: ${disk_usage}%" >> $LOG_FILE
if [ $disk_usage -ge 90 ]; then
echo "CRITICAL: Disk usage is critically high!" >> $LOG_FILE
elif [ $disk_usage -ge 70 ]; then
echo "WARNING: Disk usage is getting high." >> $LOG_FILE
else
echo "OK: Disk usage is normal." >> $LOG_FILE
fi
## 检查内存
mem_total=$(free -m | grep Mem | awk '{print $2}')
mem_used=$(free -m | grep Mem | awk '{print $3}')
mem_percentage=$((mem_used * 100 / mem_total))
echo "Memory usage: ${mem_percentage}%" >> $LOG_FILE
if [ $mem_percentage -ge 90 ]; then
echo "CRITICAL: Memory usage is critically high!" >> $LOG_FILE
elif [ $mem_percentage -ge 70 ]; then
echo "WARNING: Memory usage is getting high." >> $LOG_FILE
else
echo "OK: Memory usage is normal." >> $LOG_FILE
fi
## 检查关键服务
for service in sshd cron; do
if pgrep -x "$service" > /dev/null; then
echo "$service is running" >> $LOG_FILE
else
echo "WARNING: $service is not running" >> $LOG_FILE
fi
done
## 结束日志
echo "--------------------------------" >> $LOG_FILE
echo "Check completed at $(date)" >> $LOG_FILE
## 显示日志位置
echo "System check completed. Log saved to $LOG_FILE"
EOF
## 使脚本可执行
chmod +x daily_check.sh
## 运行脚本
./daily_check.sh
要调度这个脚本每天运行,你通常会使用 cron 系统。以下是设置方法:
## 展示如何设置 cron 任务(在本实验环境中不要实际创建)
echo "To schedule this script to run daily at 9 AM, you would use:"
echo "crontab -e"
echo "And add the line:"
echo "0 9 * * * /home/labex/project/daily_check.sh"
这展示了你所学的 Linux 条件测试命令如何应用于创建实用的系统监控工具。
在这个实验中,你学习了如何使用 Linux 条件测试来评估不同类型的条件,并根据结果做出决策。以下是你所完成内容的总结:
test 命令的基础知识,以及如何检查文件属性,如文件是否存在、是否可读和文件大小。==、!=、-z 和 -n 等运算符进行字符串比较,以验证输入并根据文本内容做出决策。-eq、-ne、-lt、-gt、-le 和 -ge 等运算符进行数值比较,以评估数值。&&、||、!) 组合多个条件,以创建复杂的决策逻辑。这些技能是 Linux 中 shell 脚本编写和系统管理的基础。测试条件并根据结果采取不同行动的能力使你能够创建可以自动化任务、验证输入、处理错误和监控系统健康状况的脚本。
你所学内容的一些实际应用包括:
随着你继续使用 Linux,你会发现条件测试几乎是你创建或维护的每个 shell 脚本的重要组成部分。