现在后端开发程序员,基本上都需要具备基本的运维能力,所以shell脚本编程也是非常重要的。所以需要掌握shell脚本的知识,并具备编写shell脚本的能力,我想把最近这几年在广州图书馆看的关于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" ]; then
echo "First argument is: $1"
fi
# 设置退出状态码
exit 0
2.变量与参数
概念 | 描述 | 示例 |
---|---|---|
局部变量 | 只在当前脚本或子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 ]]; then
echo "$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/bash
a=5
b=10
# 基本结构
if [ $a -lt $b ]; then
echo "$a is less than $b"
elif [ $a -gt $b ]; then
echo "$a is greater than $b"
else
echo "$a is equal to $b"
fi
# 测试运算符
if [[ $a -eq $b ]]; then
echo "$a is equal to $b"
else
echo "$a is not equal to $b"
fi
# 逻辑运算符
if [[ $a -lt 10 && $a -gt 1 ]]; then
echo "$a is between 1 and 10"
fi
# 文件测试
if [[ -f "example.txt" ]]; then
echo "The file example.txt exists."
fi
# 字符串测试
string="Hello World"
if [[ "$string" == "Hello*" ]]; then
echo "The string starts with 'Hello'"
fi
# 算术比较
if [[ $a -gt $b ]]; then
echo "$a is greater than $b"
fi
# 复合条件
if [[ ($a -eq 5) && ($b -lt 15) ]]; then
echo "Both conditions are true"
fi
# 反义操作
if [[ ! $a -eq $b ]]; then
echo "$a is not equal to $b"
fi
4.循环语句
概念 | 描述 | 示例 |
---|---|---|
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; do
echo "Welcome $i times"
done
# while 循环
counter=0
while [ $counter -lt 5 ]; do
echo "In while loop, counter is $counter"
((counter++))
done
# until 循环
counter=0
until [ $counter -ge 5 ]; do
echo "In until loop, counter is $counter"
((counter++))
done
# C风格的for循环
for (( i=0; i<5; i++ )); do
echo "C-style loop iteration $i"
done
# 循环控制
for i in 1 2 3 4 5; do
if [ $i -eq 3 ]; then
break
fi
echo "Number $i is less than 3"
done
# continue的使用
for i in 1 2 3 4 5; do
if [ $i -eq 3 ]; then
continue
fi
echo "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[@]}"; do
sum=$((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 )); then
add=$(( $1 * factorial $(( $1 - 1 )) ))
fi
echo $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.txt
7.管道符
概念 | 描述 | 示例 |
---|---|---|
管道符 | 使用| | | 将一个命令的输出作为另一个命令的输入。 |
命令链 | 可以连接多个管道,将多个命令的输出依次传递。 | 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) | command3
8.正则表达式
概念 | 描述 | 示例 |
---|---|---|
字符匹配 | 使用. 来匹配任意单个字符。 | `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]" filename
9.文本处理
概念 | 描述 | 示例 |
---|---|---|
文本查看 | 使用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.txt
10.数组
概念 | 描述 | 示例 |
---|---|---|
定义数组 | 使用空括号或数组名后跟索引来定义数组。 | 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]=a array2D[0][1]=b |
关联数组 | Bash 4.0+ 支持的类似哈希表的数组。 | declare -A assoc_array assoc_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[@]}"; do
echo "$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; do
sleep 1
done
12.进程控制
概念 | 描述 | 示例 |
---|---|---|
$$ | 当前进程的进程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 %1
13.文件系统操作
概念 | 描述 | 示例 |
---|---|---|
文件操作 | 使用touch 创建文件,rm 删除文件。 | touch newfile.txt rm oldfile.txt |
目录操作 | 使用mkdir 创建目录,rmdir 删除空目录。 | mkdir newdir rmdir emptydir |
文件权限 | 使用chmod 改变文件权限。 | chmod +x script.sh |
文件属性 | 使用chown 改变文件所有者,chgrp 改变文件组。 | chown user filename.txt chgrp group filename.txt |
链接文件 | 使用ln 创建硬链接或软链接。 | ln -s /path/to/source /path/to/link |
文件查找 | 使用find 命令在文件系统中查找文件。 | find / -name filename.txt |
路径操作 | 使用dirname 和basename 处理文件路径。 | dirname /path/to/file basename /path/to/file |
文件比较 | 使用cmp 命令比较两个文件是否完全相同。 | cmp -l file1.txt file2.txt |
文件大小 | 使用ls -l 查看文件大小,du 检查磁盘使用情况。 | ls -l filename.txt du -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.txt
14.权限与所有权
概念 | 描述 | 示例 |
---|---|---|
用户权限 | 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 022
15.网络编程
概念 | 描述 | 示例 |
---|---|---|
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@remotehost
16.系统管理
概念 | 描述 | 示例 |
---|---|---|
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_file
17.时间与日期
概念 | 描述 | 示例 |
---|---|---|
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" date
18.性能监控
概念 | 描述 | 示例 |
---|---|---|
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
# 显示系统资源统计报告
dstat
19.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.sh
20.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; do
case $opt in
a) 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博客