通过一个多月的shell学习,总共写出30个案例,分批次进行发布,这次总共发布了5个案例,希望能够对大家的学习和使用有所帮助,更多案例会在下一次进行发布。
案例一、备份指定目录下的文件到另一个目录
1.问题
在服务器环境中,需要定期备份特定目录(如/var/www/html)中的文件到备份目录(如/backup),以防止数据丢失。
2.分析
目标:创建一个可自动化执行的备份机制。
主要步骤:检查备份目录是否存在,如果不存在则创建。
获取当前日期,用于为备份文件添加时间戳。
使用rsync等命令将源目录中的文件复制到备份目录中,并以日期命名备份文件夹。
考虑因素:权限问题,确保执行脚本的用户有足够的权限访问源目录和备份目录。
备份过程中的错误处理,如磁盘空间不足等情况。
3.流程图
4.实现
#!/bin/bash
# 源目录,可修改为需要备份的实际目录
source_dir="/var/www/html"
# 备份目录,可修改
backup_dir="/backup"
# 检查备份目录是否存在
if [! -d "$backup_dir" ]; then
mkdir -p "$backup_dir"
fi
# 获取当前日期
current_date=$(date +%Y%m%d)
backup_folder="$backup_dir/$current_date"
mkdir -p "$backup_folder"
# 使用rsync进行备份
rsync -avz --progress "$source_dir" "$backup_folder"
5.实现解析
定义了source_dir和backup_dir变量,分别表示源目录和备份目录,用户可以根据实际需求修改这些值。
通过if语句检查备份目录是否存在,如果不存在则使用mkdir -p命令创建(-p选项确保创建多层级目录时父目录不存在也能创建成功)。
使用date +%Y%m%d获取当前日期,并将其格式化为YYYYMMDD的形式,然后创建以这个日期命名的备份文件夹在备份目录下。
最后,使用rsync -avz --progress命令进行备份。-a选项表示归档模式(保持文件属性等),-v表示详细输出,-z表示在传输过程中进行压缩,--progress用于显示备份的进度。它将源目录中的所有文件和子目录复制到新创建的备份文件夹中。这种方式相对cp命令更灵活,尤其是在处理大量文件和目录时效率更高且可以更好地处理文件的更新和删除等情况。如果选择cp命令,类似cp -r $source_dir/* $backup_folder,不过cp可能在处理复杂情况(如符号链接等)时不如rsync。
案例二、统计一个文本文件中的行数、单词数和字符数
1.问题
编写一个 Shell 脚本,实现统计给定文本文件的行数、单词数和字符数,并输出结果。
2.分析
需要接收一个文件名作为参数。通过$1来获取用户在命令行输入的文件名。
要逐行读取文件内容,计算行数。可以使用while read循环。
对于单词数的计算,将每行内容按空格分割,统计单词数量。
字符数就是文件内容的总字符数,可以在读取过程中累加。
3.流程图
4.实现
#!/bin/bash
# 检查是否有文件名参数
if [ $# -eq 0 ]; then
echo "请输入文件名作为参数。"
exit 1
fi
filename=$1
# 检查文件是否存在
if [! -f $filename ]; then
echo "文件 $filename 不存在。"
exit 1
fi
line_count=0
word_count=0
char_count=0
while read line; do
line_count=$((line_count + 1))
words_in_line=( $line )
word_count=$((word_count + ${#words_in_line[@]}))
char_count=$((char_count + ${#line}))
done < $filename
echo "行数: $line_count"
echo "单词数: $word_count"
echo "字符数: $char_count"
5.实现解析
if [ $# -eq 0 ]; then... exit 1:检查命令行参数个数,如果为 0,则提示用户输入文件名并退出脚本。
filename=$1:将第一个命令行参数(文件名)赋值给变量filename。
if [! -f $filename ]; then... exit 1:检查文件是否存在,如果不存在则输出错误信息并退出。
line_count=0、word_count=0、char_count=0:初始化行数、单词数和字符数的计数器。
while read line; do... done < $filename:逐行读取文件内容。对于每一行: line_count=$((line_count + 1)):行数计数器加 1。
words_in_line=( $line ):将行内容按空格分割成单词数组。
word_count=$((word_count + ${#words_in_line[@]})):计算该行单词数并累加到单词数计数器。
char_count=$((char_count + ${#line})):计算该行字符数并累加到字符数计数器。
最后,输出行数、单词数和字符数的统计结果。
6.结果验证
运行脚本,再脚本后跟需要统计的文本文件,输出即可
若是后面不接需要统计的文本文件,则输出以下结果
案例三、输出本机的ip
1.问题
编写一个 Shell 脚本,获取本地主机的 IP 地址并输出,如果获取失败则提示无法获取。
2.分析
首先使用hostname -I命令获取本地主机所有的 IP 地址信息,它可能返回多个 IP(以空格分隔),这里我们只取第一个(通过awk '{print $1}')并赋值给变量ip_addr。
然后检查ip_addr变量是否有值(非空),如果有值则输出该 IP 地址,否则输出无法获取 IP 地址的提示信息。
3.流程图
4.实现
ip_addr=$(hostname -I | awk '{print $1}')
if [ -n "$ip_addr" ]; then
echo "IP 地址为:$ip_addr"
else
echo "无法获取 IP 地址。"
fi
5.实现解析
地址(包括 IPv4 和 IPv6,如果配置了的话),它返回一个字符串,其中 IP 地址之间以空格分隔。
过管道|将hostname -I的输出传递给awk,从而提取出第一个 IP 地址,并将其赋值给变量ip_addr。
if [ -n "$ip_addr" ]; then... else... fi:[ -n "$ip_addr" ]:这是一个条件判断语句,-n选项用于检查变量ip_addr是否非空(即包含至少一个字符)。如果ip_addr非空,条件为真,执行then后面的语句;如果ip_addr为空,条件为假,执行else后面的语句。
echo "IP 地址为:$ip_addr":如果ip_addr有值,输出 IP 地址信息。
echo "无法获取 IP 地址。":如果ip_addr为空,输出无法获取 IP 地址的提示。
6.结果验证
案例四、在指定目录下查找特定扩展名的文件并输出其路径
1.问题
编写一个 Shell 脚本,实现在用户指定的目录及其子目录中查找指定扩展名的文件,并输出这些文件的完整路径。
2.分析
需要获取两个参数,一个是要搜索的目录路径,另一个是要查找的文件扩展名。
使用find命令在指定目录及其子目录中进行搜索。
对find命令的输出结果进行处理和输出。
3.流程图
4.实现
#!/bin/bash
# 检查参数个数是否正确
if [ $# -ne 2 ]; then
echo "用法: $0 [搜索目录] [文件扩展名]"
exit 1
fi
search_dir="$1"
file_extension="$2"
# 使用find命令查找文件
found_files=$(find $search_dir -name "*.$file_extension")
# 输出找到的文件路径
for file in $found_files; do
echo $file
done
5.实现解析
if [ $# -ne 2 ]; then... exit 1:检查命令行参数个数是否为 2,如果不是,则提示脚本用法并退出。
search_dir="$1"和file_extension="$2":将命令行传入的搜索目录和文件扩展名参数分别赋值给变量。
found_files=$(find $search_dir -name "*.$file_extension"):使用find命令在$search_dir目录及其子目录中查找文件名以指定扩展名结尾的文件,并将结果赋值给found_files变量。-name选项用于指定文件名匹配模式。
for file in $found_files; do... done:遍历found_files中的每个文件路径,并输出。
6.结果验证
正确输出结果如下
错误输出结果如下
案例五、能够定期检查指定网站是否可以正常访问,并记录访问状态
1.问题
创建一个 Shell 脚本,实现定时检查特定网站的可访问性,并将每次检查的结果(包括时间、网站 URL 和是否可访问状态)记录下来,以便后续查看网站的可用性变化情况。
2.分析
参数获取:需要接收要检查的网站 URL 作为输入参数。可以通过命令行参数传递的方式获取。
检查方法:使用curl或wget等网络工具来尝试访问网站。根据这些工具的返回值或状态码来判断网站是否可访问。例如,curl命令可以通过设置选项获取 HTTP 状态码,如果状态码为200,则通常表示网站可正常访问。
定时机制:使用while循环结合sleep命令实现定时检查。可以设置一个合适的时间间隔,如每隔几分钟检查一次。
记录方式:将每次检查的结果(时间戳、网站 URL、访问状态)以一定格式写入到日志文件中,方便查看和分析。
3.流程图
4.实现
#!/bin/bash
# 检查参数个数
if [ $# -ne 1 ]; then
echo "用法: $0 [网站URL]"
exit 1
fi
website_url="$1"
log_file="website_access_status.log"
check_interval=300 # 检查间隔时间(秒)
# 函数:检查网站是否可访问
check_website() {
if curl -s --head --fail "$website_url" > /dev/null; then
echo "可访问"
else
echo "不可访问"
fi
}
while true; do
current_time=$(date +"%Y-%m-%d %H:%M:%S")
access_status=$(check_website)
echo "$current_time - $website_url - $access_status" >> $log_file
sleep $check_interval
done
5.实现解析
这里期望只有一个参数,即要检查的网站 URL。
website_url="$1":将命令行传入的参数(网站 URL)赋值给变量website_url。
log_file="website_access_status.log":指定记录网站访问状态的日志文件名。
check_interval=300:设置检查网站的时间间隔为 300 秒(5 分钟)。
表示静默模式,不输出详细信息。--head选项只获取 HTTP 头信息。--fail选项使curl在服务器返回的 HTTP 状态码大于等于 400 时返回错误。如果curl命令执行成功(即网站可访问,状态码为 200 等正常情况),函数返回“可访问”,否则返回“不可访问”。
获取当前时间的字符串表示,格式为“年 - 月 - 日 时:分:秒”。
赋值给access_status变量。
访问状态以特定格式追加到日志文件log_file中。
sleep $check_interval:使脚本暂停check_interval秒,实现定时检查的功能。
6.结果验证
执行脚本查看百度的网址是否可以访问,通过查看日志可以看到百度的网站是可以访问的,再随机访问一个网站,可以看到是不可访问的
若是脚本执行后不加网址,则会输出如下结果
标签:count,shell,ip,备份,30,echo,案例,line,目录 From: https://blog.csdn.net/2401_82737195/article/details/143745876