现在后端开发程序员,基本上都需要具备基本的运维能力,所以shell脚本编程也是非常重要的。所以需要掌握shell脚本的知识,并具备编写shell脚本的能力,我想把最近这几年在广州图书馆看的关于shell脚本的知识做个总结汇总,便于日常复习,当然面试也是有帮助。
目录
1.基础语法
2.变量与参数
3.条件语句
4.循环语句
5.函数
6.输入和输出重定向
7.管道符
8.正则表达式
9.文本处理
10.数组
11.信号与陷阱
12.进程控制
13.文件系统操作
14.权限与所有权
15.网络编程
16.系统管理
17.时间与日期
18.性能监控
19.Shell脚本调试
20.Shell脚本优化
1.基础语法
| 概念 | 描述 | 示例 | 
|---|---|---|
| 脚本文件 | 脚本是一个包含一系列命令的文本文件。 | #!/bin/bash | 
| 脚本解释器 | 指定脚本运行时使用的解释器。 | #!/bin/bash或#!/bin/sh | 
| 注释 | 以 #开头的行,解释器会忽略。 | # This is a comment | 
| 命令行参数 | 传递给脚本的参数,如 $1、$2等。 | ./script.sh arg1 arg2 | 
| 退出状态码 | 命令执行后返回的数值,通常0表示成功,非0表示错误。 | exit 0或exit 1 | 
| 命令分隔符 | 用于分隔命令的字符,通常是分号 ;或换行符\n。 | echo "Hello"; echo "World" | 
| 命令组合 | 组合多个命令执行,如使用 &&或` | |
| 命令替换 | 使用反引号或 $()执行命令,并将输出替换到当前位置。 | filename=ls` | 
| 通配符 | 匹配文件名的字符,如 *、?等。 | rm -rf *.tmp | 
示例脚本:
#!/bin/bash
# 这是一个简单的Shell脚本示例# 打印欢迎信息
echo "Welcome to the Shell Scripting Tutorial!"# 使用命令行参数
if [ -n "$1" ]; thenecho "First argument is: $1"
fi# 设置退出状态码
exit 02.变量与参数
| 概念 | 描述 | 示例 | 
|---|---|---|
| 局部变量 | 只在当前脚本或子shell中有效。 | local_var="local scope" | 
| 环境变量 | 可供所有程序和子shell使用。 | PATH="/usr/local/bin:$PATH" | 
| 位置参数 | 传递给脚本的参数,如 $1、$2等。 | echo "First arg: $1" | 
| 特殊参数 | 特殊用途的变量,如 $0是脚本名,$#是参数个数。 | echo "Script name: $0" | 
| 字符串操作 | 对字符串进行操作,如切割、连接、替换等。 | firstname="John"; lastname="Doe"; full_name="$firstname $lastname" | 
| 数字操作 | 进行数学运算,如加、减、乘、除等。 | sum=$((1 + 2)) | 
| 算术扩展 | 使用双括号 []进行更复杂的数学运算。 | [[ $a > $b ]] && echo "$a is greater than $b" | 
| 变量展开 | 将变量的值替换到当前位置。 | echo "The value is $local_var" | 
| 默认值 | 如果变量未定义,则使用默认值。 | echo "Value: ${var:-default_value}" | 
| 间接引用 | 通过变量名获取变量的值。 | name="local_var"; echo "${!name}" | 
| 读取变量 | 从用户那里读取输入。 | read -p "Enter your name: " username | 
示例脚本:
#!/bin/bash# 定义一个局部变量
local_var="I am a local variable."# 打印局部变量
echo "Local variable: $local_var"# 定义一个环境变量
export USER="John Doe"# 打印环境变量
echo "User: $USER"# 使用位置参数
echo "The first argument is: $1"# 使用特殊参数
echo "Number of arguments: $#"
echo "Script name: $0"# 字符串操作
firstname="John"
lastname="Doe"
full_name="${firstname} ${lastname}"
echo "Full name: $full_name"# 数字操作
sum=$((3 + 4))
echo "Sum: $sum"# 算术扩展
a=10
b=5
if [[ $a > $b ]]; thenecho "$a is greater than $b"
fi# 变量展开
echo "The value is ${local_var:-default}."# 间接引用
name="local_var"
echo "Indirect reference: ${!name}"# 读取变量
read -p "Enter your age: " age
echo "You are $age years old."3.条件语句
| 概念 | 描述 | 示例 | 
|---|---|---|
| 基本结构 | 使用 if、elif(else if的简写)、else和fi来构建条件语句。 | if [ condition ]; then ... elif [ another_condition ]; then ... else ... fi | 
| 测试运算符 | 用于比较和测试条件,如 -eq(等于)、-ne(不等于)等。 | [[ $a -eq $b ]] | 
| 逻辑运算符 | 用于组合多个测试,如 &&(逻辑与)和` | |
| 文件测试 | 检查文件的存在性、权限等。 | [[ -f "filename" ]] | 
| 字符串测试 | 检查字符串的模式匹配、长度等。 | [[ "$string" == "pattern" ]] | 
| 算术比较 | 对两个数值进行比较。 | [[ $a -gt $b ]] | 
| 复合条件 | 使用圆括号 []来组合多个条件。 | [[ ($a -eq $b) && ($c -ne $d) ]] | 
| 反义操作 | 使用感叹号 !来取反条件。 | [[ ! $a -eq $b ]] | 
示例脚本:
#!/bin/basha=5
b=10# 基本结构
if [ $a -lt $b ]; thenecho "$a is less than $b"
elif [ $a -gt $b ]; thenecho "$a is greater than $b"
elseecho "$a is equal to $b"
fi# 测试运算符
if [[ $a -eq $b ]]; thenecho "$a is equal to $b"
elseecho "$a is not equal to $b"
fi# 逻辑运算符
if [[ $a -lt 10 && $a -gt 1 ]]; thenecho "$a is between 1 and 10"
fi# 文件测试
if [[ -f "example.txt" ]]; thenecho "The file example.txt exists."
fi# 字符串测试
string="Hello World"
if [[ "$string" == "Hello*" ]]; thenecho "The string starts with 'Hello'"
fi# 算术比较
if [[ $a -gt $b ]]; thenecho "$a is greater than $b"
fi# 复合条件
if [[ ($a -eq 5) && ($b -lt 15) ]]; thenecho "Both conditions are true"
fi# 反义操作
if [[ ! $a -eq $b ]]; thenecho "$a is not equal to $b"
fi4.循环语句
| 概念 | 描述 | 示例 | 
|---|---|---|
| for循环 | 遍历列表中的每个元素执行命令。 | for i in 1 2 3; do echo "Welcome $i times"; done | 
| while循环 | 只要条件为真,就不断执行命令。 | while [ condition ]; do ... done | 
| until循环 | 与 while相反,只要条件为假,就不断执行命令。 | until [ condition ]; do ... done | 
| C风格的for循环 | 类似于C语言的 for循环,提供初始化、条件和迭代表达式。 | for (( init; condition; increment )); do ... done | 
| 循环控制 | break用于退出循环,continue用于跳过当前迭代。 | break或continue | 
| 循环参数 | 使用特殊变量,如 $@遍历所有循环参数。 | for param in "$@"; do echo "$param"; done | 
示例脚本:
#!/bin/bash# for 循环
for i in 1 2 3 4 5; doecho "Welcome $i times"
done# while 循环
counter=0
while [ $counter -lt 5 ]; doecho "In while loop, counter is $counter"((counter++))
done# until 循环
counter=0
until [ $counter -ge 5 ]; doecho "In until loop, counter is $counter"((counter++))
done# C风格的for循环
for (( i=0; i<5; i++ )); doecho "C-style loop iteration $i"
done# 循环控制
for i in 1 2 3 4 5; doif [ $i -eq 3 ]; thenbreakfiecho "Number $i is less than 3"
done# continue的使用
for i in 1 2 3 4 5; doif [ $i -eq 3 ]; thencontinuefiecho "Number $i is not equal to 3"
done# 循环参数
echo "Enter numbers to sum:"
read -a numbers
echo "You entered: ${numbers[@]}"
sum=0
for num in "${numbers[@]}"; dosum=$((sum + num))
done
echo "The sum is: $sum"5.函数
| 概念 | 描述 | 示例 | 
|---|---|---|
| 定义 | 使用 function关键字或大括号定义一个函数。 | function greet { echo "Hello!"; }或greet() { echo "Hello!"; } | 
| 参数 | 函数可以接收参数,通过 $1,$2等访问。 | add() { echo "Sum is $(($1 + $2)); } } | 
| 返回值 | 使用 return语句从函数返回一个值。 | add_numbers() { return $(($1 + $2)); } | 
| 作用域 | 函数内部定义的变量在函数外部不可见。 | local_var="local to function" | 
| 递归 | 函数可以调用自身,实现递归。 | factorial() { if (( $1 > 1 )); then factorial $(($1 - 1)); fi; echo $1; } | 
| 函数调用 | 使用函数名加参数调用函数。 | greet或add 10 15 | 
| 匿名函数 | 不给函数命名,直接定义并使用。 | (echo "Hello") & | 
示例脚本:
#!/bin/bash# 定义一个简单的函数
function greet {echo "Hello from a function!"
}# 使用函数
greet# 使用大括号定义函数
add() {echo "Sum is $(($1 + $2))"
}# 调用add函数
add 10 15# 带返回值的函数
add_numbers() {return $(($1 + $2))
}# 使用返回值
result=$(add_numbers 5 10)
echo "The result is $result"# 局部变量
function test {local local_var="I am local to the function"echo "$local_var"
}# 递归函数
factorial() {if (( $1 > 1 )); thenadd=$(( $1 * factorial $(( $1 - 1 )) ))fiecho $add
}# 调用递归函数
factorial 5# 匿名函数
(echo "Hello from an anonymous function") &6.输入和输出重定向
| 概念 | 描述 | 示例 | 
|---|---|---|
| 输出重定向 | 使用 >将命令的输出重定向到文件。 | ls > file_list.txt | 
| 追加输出 | 使用 >>将输出追加到现有文件的末尾。 | echo "Appended line" >> file_list.txt | 
| 输入重定向 | 使用 <将文件内容作为命令的输入。 | sort < sorted.txt | 
| 管道符 | 使用 | | |将一个命令的输出作为另一个命令的输入。 | 
| 错误重定向 | 使用 2>将错误信息重定向到文件。 | rm non_existent_file 2> error.txt | 
| 错误追加 | 使用 2>>将错误信息追加到文件末尾。 | rm non_existent_file 2>> error.txt | 
| 同时重定向输入和输出 | 使用 >和<同时对命令的输出和错误进行重定向。 | make 2>&1 make_errors.txt | 
| 管道和重定向组合 | 将多个命令和重定向组合使用。 | `grep "error" log.txt | 
示例脚本:
#!/bin/bash# 输出重定向
echo "Redirecting output to a file"
ls > file_list.txt# 追加输出到现有文件
echo "Appending to the file"
echo "Another line" >> file_list.txt# 输入重定向
sort < sorted.txt > sorted_output.txt# 使用管道符
echo "Using a pipe to filter the output of 'ls'"
ls | grep "txt"# 重定向错误信息
echo "Redirecting error output"
rm non_existent_file 2> error.txt# 追加错误信息到文件末尾
rm non_existent_file 2>> error.txt# 同时重定向输出和错误信息
make 2>&1 > make_output.txt# 组合管道和重定向
grep "error" log.txt | sort > sorted_errors.txt7.管道符
| 概念 | 描述 | 示例 | 
|---|---|---|
| 管道符 | 使用| | | 将一个命令的输出作为另一个命令的输入。 | 
| 命令链 | 可以连接多个管道,将多个命令的输出依次传递。 | command1 | comand2 | 
| 文本处理 | 常用于文本处理命令之间的组合,如 grep、sort、awk。 | cat file.txt | awk '{print $2}' | sort | 
| 管道的退出状态 | 管道的退出状态由最后一个命令决定。 | cat non_existent_file | grep "Some text" | 
| 错误处理 | 错误信息可以通过 2>&1重定向到与标准输出相同的目的地。 | command1 2>&1 | 
| 子shell | 管道中每个命令通常在新的子shell中执行。 | `(command1; command2) | command3 | 
示例脚本:
#!/bin/bash# 使用管道符连接两个命令
echo "Hello World" | grep "World"# 命令链,连接多个命令
ls -l | grep "\.txt" | sort | less# 管道的退出状态
cat existent_file.txt | grep "Some text" # 退出状态为0,因为grep找到了匹配的文本
cat non_existent_file.txt | grep "Some text" # 退出状态非0,因为cat无法找到文件# 错误处理,将错误信息重定向到标准输出
cat non_existent_file.txt 2>&1 | grep "text" # 子shell的使用
(command1; command2) | command38.正则表达式
| 概念 | 描述 | 示例 | 
|---|---|---|
| 字符匹配 | 使用 .来匹配任意单个字符。 | `echo "Hello World" | 
| 序列匹配 | 使用 *匹配前面的字符零次或多次。 | `echo "Regular expressions are fun" | 
| 范围匹配 | 使用 []定义字符范围。 | `echo "Hello World" | 
| 组合匹配 | 使用 |来表示匹配多种模式中的任意一种。 | `echo "Hello World" | 
| 转义特殊字符 | 使用反斜杠 \来转义正则表达式中的特殊字符。 | `echo "The cost is $10" | 
| 锚点 | 使用 ^和$分别表示字符串的开始和结束。 | `echo "First line. Second line." | 
| 组匹配 | 使用圆括号 ()来分组表达式。 | `echo "Chapter 1: Introduction" | 
| 量词 | 使用 *,+,?,{n},{n,},{n,m}来指定次数。 | `echo "See spot run." | 
| 正则表达式选项 | 使用 -E选项启用扩展正则表达式。 | grep -E "^[A-Z]" filename | 
示例脚本:
#!/bin/bash# 字符匹配
echo "Hello World" | grep ".W.l."# 序列匹配
echo "Regular expressions are fun" | grep -E "ex.pres*"# 范围匹配
echo "Hello World" | grep "[aeiou]"# 组合匹配
echo "Hello World" | grep "Hello\|World"# 转义特殊字符
echo "The cost is $10" | grep -E "cost.*10"# 锚点
echo "First line. Second line." | grep -E "^First"# 组匹配
echo "Chapter 1: Introduction" | grep -E "(Chapter)\s*(\d+)"# 量词
echo "See spot run." | grep -E "run|saw"# 正则表达式选项
grep -E "^[A-Z]" filename9.文本处理
| 概念 | 描述 | 示例 | 
|---|---|---|
| 文本查看 | 使用 cat、less、more等命令查看文件内容。 | cat filename.txt或less filename.txt | 
| 文本搜索 | 使用 grep搜索文本文件中的特定模式。 | grep "pattern" filename.txt | 
| 文本替换 | 使用 sed或awk进行文本替换。 | sed 's/old/new/g' filename.txt | 
| 文本排序 | 使用 sort对文本文件中的行进行排序。 | sort -n filename.txt | 
| 行处理 | 使用 awk进行复杂的行处理,如选择、排序和计算。 | awk '{print $1, $2}' filename.txt | 
| 字段处理 | 使用 cut命令处理文本文件的字段。 | cut -d ',' -f 1,2 filename.csv | 
| 列处理 | 使用 column命令对文本文件进行格式化输出。 | column -t filename.txt | 
| 行数统计 | 使用 wc命令统计文本文件的行数、单词数和字节数。 | wc filename.txt | 
| 文本比较 | 使用 diff命令比较两个文本文件的差异。 | diff file1.txt file2.txt | 
示例脚本:
#!/bin/bash# 文本查看
cat filename.txt
less filename.txt# 文本搜索
grep "Important" filename.txt# 文本替换
sed -i 's/old/new/g' filename.txt# 文本排序
sort -n filename.txt# 行处理
awk '{print $1, $2}' filename.txt# 字段处理
cut -d ',' -f 1,2 filename.csv# 列处理
column -t filename.txt# 行数统计
wc filename.txt# 文本比较
diff file1.txt file2.txt10.数组
| 概念 | 描述 | 示例 | 
|---|---|---|
| 定义数组 | 使用空括号或数组名后跟索引来定义数组。 | array[0]=one或array=(one two three) | 
| 访问数组元素 | 使用数组名和索引访问数组中的元素。 | echo "${array[0]}"或echo "${array[@]}" | 
| 遍历数组 | 用循环遍历数组中的所有元素。 | for i in "${array[@]}"; do echo "$i"; done | 
| 数组长度 | 获取数组的长度,即元素的数量。 | length=${#array[@]} | 
| 数组切片 | 获取数组的一部分。 | slice=("${array[@]:2:2}") | 
| 多维数组 | 创建和操作多维数组。 | array2D[0][0]=aarray2D[0][1]=b | 
| 关联数组 | Bash 4.0+ 支持的类似哈希表的数组。 | declare -A assoc_arrayassoc_array[key]=value | 
| 数组操作 | 对数组进行添加、删除、排序等操作。 | array=("${array[@]}" new_element | 
| 默认值 | 为数组元素设置默认值。 | array=(one two three "${array[@]}") | 
示例脚本:
#!/bin/bash# 定义数组
array=(one two three)# 访问数组元素
echo "First element is: ${array[0]}"
echo "All elements are: ${array[@]}"# 遍历数组
for i in "${array[@]}"; doecho "$i"
done# 数组长度
length=${#array[@]}
echo "Array length is: $length"# 数组切片
slice=("${array[@]:2:2}")
echo "Array slice is: ${slice[@]}"# 多维数组
array2D=([0]=(a b) [1]=(c d))
echo "${array2D[0][1]}"# 关联数组
declare -A assoc_array
assoc_array[key]=value
echo "assoc_array[key] is $assoc_array[key]"# 数组操作
array=("${array[@]}" "four")
echo "New array is: ${array[@]}"# 默认值
array=(one "${array[@]}" two)
echo "Array with default values: ${array[@]}"11.信号与陷阱
| 概念 | 描述 | 示例 | 
|---|---|---|
| 信号 | 由操作系统发送给进程的事件,用于通知或中断进程。 | kill -SIGINT PID | 
| 陷阱 | 对信号的响应,可以捕获并处理信号。 | trap "command" SIGINT | 
| 信号列表 | 列出所有可用的信号。 | trap -l | 
| 标准信号 | 如SIGKILL、SIGTERM、SIGINT等,用于结束或暂停进程。 | trap "echo 'Script terminated.'" SIGTERM | 
| 清理操作 | 在脚本退出前执行的清理工作,如删除临时文件。 | trap "rm -f /tmp/mytmpfile; exit" SIGHUP SIGINT SIGTERM | 
| 退出状态码 | 通过 $?获取上一个命令或陷阱的退出状态码。 | trap "echo 'Exit code: $?'" EXIT | 
| 递归陷阱 | 当一个陷阱中调用另一个命令时,该命令也可以设置陷阱。 | trap "new_trap" SIGINT在另一个trap中使用 | 
| 忽略信号 | 使用 trap "" SIGNAL忽略特定信号。 | trap "" SIGQUIT | 
示例脚本:
#!/bin/bash# 定义一个清理函数
cleanup() {echo "Cleaning up before exit."rm -f /tmp/mytmpfile
}# 设置SIGINT(Ctrl+C)的陷阱
trap cleanup SIGINT# 设置退出时的陷阱
trap "echo 'Script is exiting.'; exit 1" EXIT# 产生一个可被SIGINT中断的长循环
while true; dosleep 1
done12.进程控制
| 概念 | 描述 | 示例 | 
|---|---|---|
| $$ | 当前进程的进程ID。 | echo "My PID is $$" | 
| $! | 上一个后台命令的进程ID。 | sleep 60 & echo "Background PID is $!" | 
| $? | 上一个命令的退出状态码。 | `command && echo "Success" | 
| $PPID | 父进程的进程ID。 | echo "My PPID is $PPID" | 
| ps | 显示当前系统进程的状态。 | `ps aux | 
| kill | 发送信号给指定的进程。 | kill -SIGTERM $$ | 
| wait | 等待后台命令结束。 | wait $! | 
| nohup | 忽略挂起信号(SIGINT),使进程在后台持续运行。 | nohup command & | 
| & | 将命令放在后台执行。 | command & | 
| fg和bg | 将后台命令调至前台( fg),或将前台命令置于后台(bg)。 | fg %1或bg %1 | 
| trap | 捕捉信号,并执行特定的命令。 | trap "echo 'Killed'" SIGTERM | 
示例脚本:
#!/bin/bash# 显示当前进程的PID
echo "This script's PID is: $$"# 后台运行一个命令并获取其PID
sleep 60 &
echo "Background process started with PID: $!"# 等待后台命令结束
wait $!# 杀死自己
kill -SIGTERM $$# 使用nohup在后台运行一个命令忽略挂起信号
nohup my_command &# 使用ps查看进程状态
ps aux | grep "my_command"# 使用fg将后台作业调至前台
fg %1# 使用bg将前台作业置于后台
command &
bg %113.文件系统操作
| 概念 | 描述 | 示例 | 
|---|---|---|
| 文件操作 | 使用 touch创建文件,rm删除文件。 | touch newfile.txtrm oldfile.txt | 
| 目录操作 | 使用 mkdir创建目录,rmdir删除空目录。 | mkdir newdirrmdir emptydir | 
| 文件权限 | 使用 chmod改变文件权限。 | chmod +x script.sh | 
| 文件属性 | 使用 chown改变文件所有者,chgrp改变文件组。 | chown user filename.txtchgrp group filename.txt | 
| 链接文件 | 使用 ln创建硬链接或软链接。 | ln -s /path/to/source /path/to/link | 
| 文件查找 | 使用 find命令在文件系统中查找文件。 | find / -name filename.txt | 
| 路径操作 | 使用 dirname和basename处理文件路径。 | dirname /path/to/filebasename /path/to/file | 
| 文件比较 | 使用 cmp命令比较两个文件是否完全相同。 | cmp -l file1.txt file2.txt | 
| 文件大小 | 使用 ls -l查看文件大小,du检查磁盘使用情况。 | ls -l filename.txtdu -sh directory | 
| 文件内容 | 使用 cat、less、more查看文件内容。 | cat filename.txt | 
示例脚本:
#!/bin/bash# 创建一个新文件
touch newfile.txt# 删除一个文件
rm oldfile.txt# 创建一个新目录
mkdir newdir# 删除一个空目录
rmdir emptydir# 更改文件权限,使得所有用户都可以执行这个脚本
chmod +x script.sh# 更改文件所有者
chown user filename.txt# 更改文件所属组
chgrp group filename.txt# 创建一个符号链接
ln -s /path/to/source /path/to/link# 查找系统中名为filename.txt的文件
find / -name filename.txt# 获取文件路径中的目录部分
dirname /path/to/file# 获取文件路径中的文件名部分
basename /path/to/file# 比较两个文件是否完全相同
cmp -l file1.txt file2.txt# 显示文件的大小
ls -l filename.txt# 检查目录的磁盘使用情况
du -sh directory# 查看文件内容
cat filename.txt14.权限与所有权
| 概念 | 描述 | 示例 | 
|---|---|---|
| 用户权限 | Linux系统中的文件权限分为三类:所有者(owner)、组(group)和其他(others)。 | ls -l显示文件权限 | 
| 读(r) | 允许读取文件内容或列出目录内容。 | chmod r filename | 
| 写(w) | 允许修改文件内容或添加删除目录内的文件。 | chmod w filename | 
| 执行(x) | 允许执行文件或进入目录。 | chmod x filename | 
| 数字表示法 | 使用数字来表示权限:4(r)、2(w)、1(x)。 | chmod 644 filename给予所有者读写权限,组和其他只读权限 | 
| 特殊权限 | 如suid(设置用户ID)、sgid(设置组ID)、sticky bit(粘滞位)。 | chmod u+sx file给予文件suid权限和执行权限 | 
| 改变所有权 | 使用 chown命令改变文件的所有者。 | chown newuser filename | 
| 改变组 | 使用 chgrp命令改变文件的组。 | chgrp newgroup filename | 
| ACL(访问控制列表) | 提供更细粒度的权限控制。 | setfacl -m "u:john:rwx" filename | 
| umask | 定义新文件的默认权限。 | umask 022将新文件的默认权限设置为644 | 
示例脚本:
#!/bin/bash# 给文件添加读权限
chmod r filename# 设置文件权限为644(所有者读写,组和其他只读)
chmod 644 filename# 给文件添加suid权限
chmod u+s file# 改变文件的所有者为newuser
chown newuser filename# 改变文件的组为newgroup
chgrp newgroup filename# 设置ACL权限
setfacl -m "u:john:rwx" filename# 设置umask,新文件默认权限为644
umask 02215.网络编程
| 概念 | 描述 | 示例 | 
|---|---|---|
| ping | 发送ICMP ECHO请求以测试主机之间的连通性。 | ping www.example.com -c 4 | 
| curl | 用于传输数据,支持多种协议,常用于测试网络连接。 | curl -I www.example.com | 
| wget | 用于从网络上下载文件。 | wget www.example.com/somefile | 
| netstat | 显示网络连接、路由表、接口统计等网络信息。 | netstat -tuln | 
| ss | 用于检查套接字统计信息。 | ss -tunap | 
| dig | 用于DNS查找,查询DNS服务器以获取任意记录类型的信息。 | dig www.example.com | 
| nslookup | 用于查询DNS信息,获取域名的IP地址。 | nslookup www.example.com | 
| ifconfig | 配置或显示系统网络接口的信息。 | ifconfig eth0 up | 
| traceroute | 显示数据包到目的地的路径。 | traceroute www.example.com | 
| scp | 安全地复制文件到远程主机。 | scp localfile user@remotehost:/path/to/remotefile | 
| ssh | 安全地登录到远程主机。 | ssh user@remotehost | 
示例脚本:
#!/bin/bash# ping测试连通性
ping -c 4 www.example.com# 使用curl获取HTTP头部信息
curl -I www.example.com# 使用wget下载文件
wget www.example.com/somefile# 显示所有网络接口的监听状态
netstat -tuln# 检查套接字统计信息
ss -tunap# 进行DNS查找
dig www.example.com# 查询域名的IP地址
nslookup www.example.com# 配置网络接口
ifconfig eth0 up# 追踪到目的地的路径
traceroute www.example.com# 使用scp安全复制文件
scp localfile user@remotehost:/path/to/remotefile# 使用ssh安全登录远程主机
ssh user@remotehost16.系统管理
| 概念 | 描述 | 示例 | 
|---|---|---|
| whoami | 显示当前用户的用户名。 | whoami | 
| id | 显示当前用户的UID和GID。 | id | 
| passwd | 更改用户密码。 | passwd | 
| useradd | 添加新用户。 | useradd newuser | 
| userdel | 删除用户。 | userdel -r newuser | 
| groupadd | 添加新组。 | groupadd newgroup | 
| groupdel | 删除组。 | groupdel newgroup | 
| crontab | 管理定时任务。 | crontab -e | 
| top | 实时显示系统中进程的资源占用。 | top | 
| ps | 显示当前运行的进程的状态。 | ps aux | 
| kill | 发送信号给进程以终止或暂停它。 | kill PID | 
| free | 显示系统中可用和已使用的内存。 | free -m | 
| df | 报告文件系统的磁盘空间使用情况。 | df -h | 
| du | 检查文件或目录的磁盘使用情况。 | du -sh /path/to/directory | 
| tar | 归档文件,创建或提取压缩文件。 | tar -cvzf archive.tar.gz /path/to/files | 
| chattr | 更改文件的扩展属性。 | chattr +i /path/to/immutable_file | 
示例脚本:
#!/bin/bash# 显示当前用户的用户名
echo "Current user is: $(whoami)"# 显示当前用户的UID和GID
echo "User ID and Group ID: $(id -u) : $(id -g)"# 更改用户密码
passwd# 添加新用户
sudo useradd newuser# 删除用户及其家目录
sudo userdel -r newuser# 添加新组
sudo groupadd newgroup# 删除组
sudo groupdel newgroup# 编辑当前用户的crontab文件
crontab -e# 实时显示系统中进程的资源占用
top# 显示当前运行的进程的状态
ps aux# 终止进程
kill PID# 显示系统中可用和已使用的内存
free -m# 报告文件系统的磁盘空间使用情况
df -h# 检查目录的磁盘使用情况
du -sh /path/to/directory# 创建一个压缩文件
tar -cvzf archive.tar.gz /path/to/files# 使文件不可变,防止被删除或修改
sudo chattr +i /path/to/immutable_file17.时间与日期
| 概念 | 描述 | 示例 | 
|---|---|---|
| date | 显示或设置系统的日期和时间。 | date或date --set="2024-04-29 12:00:00" | 
| time | 测量命令执行的时间。 | time { command; } | 
| cal | 显示日历。 | cal或cal 04 2024 | 
| clock | 显示当前时间。 | clock | 
| sleep | 暂停执行指定的时间(秒)。 | sleep 5 | 
| timeout | 运行命令直到超时。 | timeout --foreground 1h long_running_command | 
| strptime | 将字符串解析为时间结构。 | date -d "$(strptime 2024-04-29 "%Y-%m-%d")" '+%A' | 
| timedatectl | 查看和修改系统时间和服务状态。 | timedatectl status | 
| TZ | 环境变量,用于设置时区。 | TZ="America/New_York" date | 
示例脚本:
#!/bin/bash# 显示当前日期和时间
echo "Current date and time is: $(date)"# 设置系统日期和时间
sudo date --set="2024-04-29 12:00:00"# 测量命令执行时间
time { sleep 1; }# 显示当前月份的日历
cal# 显示当前时间
clock# 暂停5秒
sleep 5# 运行一个长时间运行的命令,直到1小时后超时
timeout --foreground 1h long_running_command# 将字符串解析为时间结构并显示星期几
date -d "$(strptime 2024-04-29 "%Y-%m-%d")" '+%A'# 查看系统时间和服务状态
timedatectl status# 设置时区并显示时间
TZ="America/New_York" date18.性能监控
| 概念 | 描述 | 示例 | 
|---|---|---|
| top | 实时显示系统中进程的资源占用,CPU和内存使用最多的进程会显示在顶部。 | top | 
| htop | 提供一个彩色界面的交互式进程查看器,功能与 top类似,但更易于使用。 | htop | 
| vmstat | 报告虚拟内存统计信息。 | vmstat 1 5 | 
| iostat | 报告CPU和输入/输出设备统计信息。 | iostat 1 5 | 
| mpstat | 报告CPU统计信息。 | mpstat -P ALL 1 5 | 
| netstat | 显示网络连接、路由表、接口统计等网络信息。 | netstat -tuln | 
| free | 显示系统中可用和已使用的内存。 | free -m | 
| df | 报告文件系统的磁盘空间使用情况。 | df -h | 
| du | 检查文件或目录的磁盘使用情况。 | du -sh /path/to/directory | 
| lsof | 列出当前系统打开文件的工具。 | lsof -i :80 | 
| pidstat | 报告Linux系统中进程的统计信息。 | pidstat -u 1 5 | 
| dstat | 用于生成系统资源统计报告的工具。 | dstat | 
示例脚本:
#!/bin/bash# 实时显示进程资源占用
top# 使用htop显示进程资源占用
htop# 报告虚拟内存统计信息
vmstat 1 5# 报告CPU和输入/输出设备统计信息
iostat 1 5# 报告CPU统计信息
mpstat -P ALL 1 5# 显示网络状态信息
netstat -tuln# 显示内存使用情况
free -m# 显示磁盘空间使用情况
df -h# 检查目录的磁盘使用情况
du -sh /path/to/directory# 列出打开的文件
lsof -i :80# 报告进程的统计信息
pidstat -u 1 5# 显示系统资源统计报告
dstat19.Shell脚本调试
| 概念 | 描述 | 示例 | 
|---|---|---|
| -x选项 | 调试选项,执行脚本时打印出执行的每条命令。 | bash -x script.sh | 
| -n选项 | 不实际执行命令,只打印命令而不运行。 | bash -n script.sh | 
| set命令 | 设置或修改Shell的选项,如 -e使脚本在任何语句的执行结果不是true时就退出。 | set -e或set -x | 
| trap命令 | 捕捉信号并执行命令,用于设置陷阱,如捕捉 SIGINT信号。 | trap "echo 'Interrupted.'" SIGINT | 
| echo | 打印信息到标准输出,常用于脚本中显示变量值或调试信息。 | echo "Variable value is $var" | 
| exit状态码 | 退出脚本并返回一个状态码,通常 0表示成功,其他值表示错误。 | exit 1 | 
| caller | 在调试时显示当前的调用堆栈。 | caller | 
| source | 读取并执行文件中的命令,但不作为独立的脚本执行。 | source script.sh | 
| bashdb | Bash的调试器。 | bashdb script.sh | 
| debugger | 某些版本的Bash自带的命令行调试器。 | debugger script.sh | 
示例脚本:
#!/bin/bash# 使用-x选项调试脚本
bash -x script.sh# 使用set命令设置脚本在出现任何错误时就退出
set -e# 使用trap命令捕捉SIGINT信号
trap "echo 'Script interrupted.'" SIGINT# 使用echo命令打印变量值
echo "The value of var is $var"# 使用exit退出脚本并返回状态码
exit 1# 使用source命令执行脚本
source script.sh# 使用bashdb调试脚本
bashdb script.sh# 使用debugger调试脚本
debugger script.sh20.Shell脚本优化
| 概念 | 描述 | 示例 | 
|---|---|---|
| 代码复用 | 将重复的代码块转换为函数以提高效率和可读性。 | do_something() { ...; } | 
| 避免全局变量 | 尽量使用局部变量以减少潜在的命名冲突。 | function foo { local var=...; } | 
| 使用 getopts | 使用 getopts或getopt解析命令行参数,避免手写解析逻辑。 | while getopts "a:b:" opt; do ...; done | 
| 错误处理 | 为可能出错的命令添加错误处理逻辑。 | `command | 
| 性能优化 | 使用合适的工具和命令来提高性能,例如使用 awk而不是grep进行复杂文本处理。 | awk '{print $1}' file代替grep -o '^[^ ]*' file | 
| 使用 bash -O | 启用Bash的内置优化选项。 | bash -O extglob -c script.sh | 
| 避免子shell | 减少不必要的子shell创建,这可以通过使用 { ... }命令组完成。 | (command1; command2)改为{ command1; command2; } | 
| 代码审查 | 定期进行代码审查,以发现并修复潜在的性能问题或改进点。 | # Code review comments | 
| 避免不必要的 echo | 在不需要输出的情况下避免使用 echo,尤其是在循环中。 | echo "Looping $i times"改为注释或移除 | 
| 使用 /dev/null | 当不需要命令的输出时,重定向到 /dev/null。 | command > /dev/null 2>&1 | 
示例脚本:
#!/bin/bash# 定义一个函数以复用代码
do_something() {# ... 一些代码 ...
}# 使用getopts解析命令行参数
while getopts "a:b:" opt; docase $opt ina) arg_a=$OPTARG ;;b) arg_b=$OPTARG ;;esac
done# 错误处理
run_command || { echo "An error occurred with run_command."; exit 1; }# 使用awk提高性能
awk '{print $1}' file.txt# 避免子shell
shopt -s lastpipe
command1 | command2# 避免不必要的echo
for i in {1..10}; do# ... 一些代码 ...# 去掉或替换 echo "Looping $i times"
done# 使用/dev/null忽略输出
some_command > /dev/null 2>&1暂且先总结这些,已经包括了Shell的大部分基础知识和一些高级特性,通过这些知识点,可以写出一些实用的脚本,并且也足够应对面试了!还有哪些高级特性和写法,也欢迎各位留言评论!对了,写脚本得有写脚本的工具吧,我的另一篇博客介绍了vim的使用:vim编辑器常用操作及快捷键_vim快捷键-CSDN博客