面试题答案
一键面试设计思路
- 读取Bash历史命令记录文件,通常位于
~/.bash_history
。 - 解析每条命令记录,提取时间戳(如果存在)。
- 判断命令是否在过去一小时内执行且包含
sudo
。 - 将符合条件的命令以时间倒序排列并输出到指定文件
sudo_commands_last_hour.log
。 - 处理权限问题,确保脚本有读取历史文件和写入输出文件的权限。
关键代码段及作用
- 读取历史文件:
history_file=~/.bash_history
if [ -r "$history_file" ]; then
while IFS= read -r line; do
# 后续处理每一行命令
done < "$history_file"
else
echo "无法读取历史文件 $history_file"
exit 1
fi
这段代码检查历史文件是否可读,如果可读则逐行读取文件内容,否则输出错误信息并退出。
- 解析时间戳和命令:
timestamp_pattern='^[0-9]{10}:[0-9]{6} '
if [[ $line =~ $timestamp_pattern ]]; then
timestamp=${BASH_REMATCH[0]% }
command=${line#* }
else
# 处理没有时间戳的情况,假设是当前时间
timestamp=$(date +%s):000000
command=$line
fi
这段代码尝试从命令记录行中提取时间戳,如果提取失败则假设命令是当前时间执行的。
- 判断时间和命令内容:
current_time=$(date +%s)
one_hour_ago=$((current_time - 3600))
timestamp_value=${timestamp%%:*}
if ((timestamp_value >= one_hour_ago)) && [[ $command =~ sudo ]]; then
echo "$line" >> temp_file
fi
这里计算当前时间和一小时前的时间戳,对比命令记录的时间戳是否在过去一小时内,并且命令是否包含 sudo
,如果符合条件则将命令写入临时文件。
- 排序并输出到结果文件:
sort -r temp_file > sudo_commands_last_hour.log
rm temp_file
将临时文件中的命令按时间倒序排序并输出到最终结果文件,然后删除临时文件。
完整脚本
#!/bin/bash
history_file=~/.bash_history
if [ -r "$history_file" ]; then
temp_file=$(mktemp)
while IFS= read -r line; do
timestamp_pattern='^[0-9]{10}:[0-9]{6} '
if [[ $line =~ $timestamp_pattern ]]; then
timestamp=${BASH_REMATCH[0]% }
command=${line#* }
else
timestamp=$(date +%s):000000
command=$line
fi
current_time=$(date +%s)
one_hour_ago=$((current_time - 3600))
timestamp_value=${timestamp%%:*}
if ((timestamp_value >= one_hour_ago)) && [[ $command =~ sudo ]]; then
echo "$line" >> $temp_file
fi
done < "$history_file"
if [ -w "sudo_commands_last_hour.log" ]; then
sort -r $temp_file > sudo_commands_last_hour.log
else
echo "无法写入文件 sudo_commands_last_hour.log"
fi
rm $temp_file
else
echo "无法读取历史文件 $history_file"
exit 1
fi