Shell脚本知识点汇总表格总结

         现在后端开发程序员,基本上都需要具备基本的运维能力,所以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
命令分隔符用于分隔命令的字符,通常是分号;或换行符\necho "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.条件语句
概念描述示例
基本结构使用ifelif(else if的简写)、elsefi来构建条件语句。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
文本处理常用于文本处理命令之间的组合,如grepsortawkcat 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.文本处理
概念描述示例
文本查看使用catlessmore等命令查看文件内容。cat filename.txt 或 less filename.txt
文本搜索使用grep搜索文本文件中的特定模式。grep "pattern" filename.txt
文本替换使用sedawk进行文本替换。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 &
fgbg将后台命令调至前台(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
路径操作使用dirnamebasename处理文件路径。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
文件内容使用catlessmore查看文件内容。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
bashdbBash的调试器。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使用getoptsgetopt解析命令行参数,避免手写解析逻辑。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/nullcommand > /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博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值