Shell脚本的使用
sublimetext
ctrl+shift +p -> Advance Install Package 输入ChineseLocalizations
在CentOS中,/etc/shells
文件列出了系统上可用的Shell。不同Shell之间存在语法和特性上的差异,常见的几种Shell如下:
1. Bash (/bin/bash
, /usr/bin/bash
)
- 全称:Bourne Again Shell
- 解释器路径:
/bin/bash
、/usr/bin/bash
- 特点:
- 是大多数Linux系统的默认Shell,包括CentOS。
- 提供丰富的功能,包括命令历史、命令补全、别名、脚本支持等。
- 语法兼容POSIX标准,并向下兼容传统的
sh
Shell。 - 广泛支持变量、条件判断、循环和函数等功能,是Linux系统中最常用的Shell。
2. Sh (/bin/sh
, /usr/bin/sh
)
- 全称:Bourne Shell
- 解释器路径:通常在CentOS中,
/bin/sh
和/usr/bin/sh
是指向/bin/bash
的软链接。 - 特点:
- 是Unix系统上最早的Shell之一,也是POSIX标准Shell的基础。
- 相比于Bash,功能较为简单,主要用于运行兼容POSIX的Shell脚本。
- Linux上
sh
通常是bash
的链接,因此在CentOS中执行/bin/sh
实际上是在运行bash
的简化版本。
3. Tcsh (/bin/tcsh
)
- 全称:TENEX C Shell
- 解释器路径:
/bin/tcsh
- 特点:
tcsh
是csh
(C Shell)的增强版本,语法风格类似于C语言。- 支持自动补全、历史记录和交互式Shell功能,比原始
csh
更具可用性。 - 在脚本方面不如
bash
或sh
常用,主要用于交互式环境。
4. Csh (/bin/csh
)
- 全称:C Shell
- 解释器路径:
/bin/csh
- 特点:
- C Shell 语法和C语言类似,但缺少
bash
或sh
的一些标准功能。 - 提供了别名、历史记录、Job控制等功能。
- 脚本编写不如
bash
流行,因为其语法在兼容性和功能上不及其他Shell。
- C Shell 语法和C语言类似,但缺少
Shell | 常用路径 | 语法特点 | 常用场景 |
---|---|---|---|
Bash | /bin/bash | POSIX兼容,功能丰富 | 常见默认Shell和脚本编写 |
Sh | /bin/sh (链接到/bin/bash ) | 简单POSIX兼容 | 传统脚本,兼容性要求高 |
Tcsh | /bin/tcsh | 类C语言语法 | 交互式使用 |
Csh | /bin/csh | 类C语言语法 | 交互式使用(较少用) |
在Linux中执行脚本有多种方式,
取决于脚本的类型和执行环境。以下是一些常见的方法:
1. 执行Bash脚本(.sh文件)
如果你的脚本是一个Shell脚本(例如.sh
文件),可以通过以下步骤执行:
./script.sh
- 注意:在执行前,确保脚本文件有执行权限。如果没有执行权限,可以通过以下命令赋予权限:
chmod +x script.sh
2. 使用Cron定时任务执行脚本
你可以使用cron
来定期执行脚本。首先编辑crontab文件:
crontab -e
然后添加定时任务,例如每天凌晨3点执行脚本:
0 3 * * * /path/to/script.sh
3. 通过SSH远程执行脚本
如果你想在远程机器上执行脚本,可以通过ssh
命令远程登录并执行脚本:
ssh user@remote_host 'bash -s' < script.sh
4. 通过系统启动时自动执行脚本
你可以将脚本添加到系统启动时执行的配置中,例如/etc/rc.local
,或者使用systemd服务管理器来创建一个自启动服务。
5. 在脚本的路径前加上“.”或者 source。
使用 source
命令来执行脚本时,脚本中的变量和修改只会作用在当前Shell进程的环境中,不会影响其他终端窗口或其他Shell进程。
当在一个终端窗口中执行 source script.sh
,该脚本中的变量仅在当前Shell进程中生效。
其他窗口运行的Shell是不同的进程,因此无法自动共享变量或环境的更改。
所有终端生效
如果希望在所有终端窗口都能访问某个变量,可以将变量配置在Shell的启动文件中,通常是以下几个文件之一:
-
全局的Shell配置文件(会影响所有用户的Shell环境):
/etc/profile
/etc/bash.bashrc
(如果使用的是bash
Shell)
-
当前用户的Shell配置文件(仅影响当前用户的Shell环境):
~/.bashrc
或~/.bash_profile
(在bash
中)~/.zshrc
(在zsh
中)
将变量设置加入这些文件中后,重新打开一个终端窗口或在当前窗口执行 source ~/.bashrc
,即可在其他窗口中访问这些变量。
例如,将以下变量设置加入 ~/.bashrc
:
export MY_VAR="Hello, World!"
然后执行:
source ~/.bashrc
这样一来,每个新打开的终端窗口中都可以访问到 MY_VAR
。
变量
在 Shell 脚本中,变量是重要的组成部分。变量分为系统预定义变量、自定义变量和特殊变量。export
命令则用于导出变量,使其在子进程中可用。以下是关于这些概念的详细说明和使用示例。
1. 系统预定义变量
系统预定义变量是 Shell 自动定义的,通常代表一些系统信息或运行时信息。以下是一些常见的系统预定义变量:
$HOME
:当前用户的主目录。$PATH
:系统查找命令的路径。$USER
:当前登录的用户名。$PWD
:当前工作目录。$SHELL
:当前使用的 Shell 类型。$?
:上一条命令的退出状态。返回 0 表示成功,非 0 表示失败。
示例:
echo "Home Directory: $HOME"
echo "Current User: $USER"
echo "Current Directory: $PWD"
echo "Shell Type: $SHELL"
echo "Last Command Status: $?"
2. 自定义变量
自定义变量是用户自己定义的变量。定义时直接使用 变量名=值
的格式,注意等号左右不能有空格。
定义和使用自定义变量的示例:
- 定义变量:变量名=变量值,注意等号前后不能有空格。
- 撤销变量:使用
unset
变量名。 - 声明静态变量:
readonly
变量,且不能使用unset
撤销。
my_var="Hello World" # 定义变量
echo $my_var # 使用变量
注意:自定义变量的作用范围默认只在当前 Shell 中,不会传递到子进程中。
3. export
命令
export
命令用于将自定义变量变成环境变量
,使其可以在当前 Shell 及其子进程
中被访问到。
使用 export
的示例:
my_var="Hello World"
export my_var # 将变量导出到环境变量
bash # 启动一个子 Shell
echo $my_var # 在子 Shell 中可以访问
exit # 退出子 Shell
直接定义和导出变量:
export my_var="Hello World"
4. 特殊变量
Shell 中有一些特殊的变量,用于在脚本中传递参数和处理命令行信息。这些特殊变量通常以 $
开头。
特殊变量 | 含义 |
---|---|
$0 | 脚本名或命令名 |
$1, $2, ... | 脚本的第 1 个、第 2 个参数,依次类推 |
$# | 传递给脚本的参数个数 |
$* | 传递给脚本的所有参数(作为一个整体) |
$@ | 传递给脚本的所有参数(分别对待) |
$$ | 当前脚本的进程 ID(PID) |
$? | 上一个命令的退出状态,如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量的值为非 0(具体是个数,由命令自己来决定),则证明上一个命令执行不正确。 |
$! | 上一个后台运行的进程的 PID |
特殊变量的示例:
#!/bin/bash
echo "Script Name: $0"
echo "First Argument: $1"
echo "Second Argument: $2"
echo "Number of Arguments: $#"
echo "All Arguments as a single string: $*"
echo "All Arguments separately: $@"
echo "Process ID: $$"
echo "Last Command Status: $?"
echo "Last Background Process ID: $!"
运行示例:
将上述脚本保存为 test.sh
,然后运行:
bash test.sh arg1 arg2
输出将显示脚本名、参数、进程 ID 等信息。
- 系统预定义变量 提供系统和运行环境信息。
- 自定义变量 用于在脚本中存储和传递数据。
export
命令 将变量变为环境变量,使其在子进程中可见。- 特殊变量 提供脚本和命令行的信息,有助于脚本参数的处理和执行状态的检查。
运算符
在 Linux Shell 中,$(( ))
和 $[]
都用于整数算术运算,但 $(( ))
更加推荐使用。以下是两者的详细作用和区别:
1. $(( ))
用法
$(())
是标准的、推荐使用的整数运算符。- 适合执行加、减、乘、除、取余等整数运算。
- 支持嵌套和组合运算。
示例:
result=$(( 5 + 3 )) # result=8
echo $result
优点:
- 它是 POSIX 标准,适用于大多数 Shell(如 Bash 和 Zsh)。
- 支持复杂的嵌套和组合运算,如
result=$(( (5 + 3) * 2 ))
。
2. $[]
用法
$[]
也是用于整数运算的早期语法,类似于$(( ))
。- 基本操作和
$(( ))
类似,但$(( ))
更通用、可读性更好,因此$[]
在新的脚本中不再推荐使用。
示例:
result=$[ 5 + 3 ] # result=8
echo $result
缺点:
- 不属于 POSIX 标准,主要在 Bash 中使用,兼容性较差。
- 在新的脚本或现代环境下不再推荐使用。
总结
- 推荐使用
$(( ))
进行整数运算,兼容性更好、功能更强大,符合 POSIX 标准。 $[]
是旧语法,尽量避免使用。
条件判断
在 Linux Shell 中,条件判断通常用于控制脚本执行的逻辑。常见的条件判断包括数值比较、字符串比较、文件属性判断等。以下是一些常用的条件判断方法和示例。
1. 数值比较
用于比较两个数值。可以使用 -eq
、-ne
、-gt
、-lt
等操作符。
操作符 | 含义 |
---|---|
-eq | 等于 |
-ne | 不等于 |
-gt | 大于 |
-lt | 小于 |
-ge | 大于等于 |
-le | 小于等于 |
示例:
#!/bin/bash
num1=10
num2=20if [ $num1 -eq $num2 ]; thenecho "num1 is equal to num2"
elif [ $num1 -gt $num2 ]; thenecho "num1 is greater than num2"
elseecho "num1 is less than num2"
fi
2. 字符串比较
用于比较字符串。可以使用 =
、!=
、-z
、-n
等操作符。
操作符 | 含义 |
---|---|
= | 字符串相等 |
!= | 字符串不等 |
-z | 字符串长度为 0 |
-n | 字符串长度不为 0 |
示例:
#!/bin/bash
str1="hello"
str2="world"if [ "$str1" = "$str2" ]; thenecho "str1 is equal to str2"
elif [ -z "$str1" ]; thenecho "str1 is empty"
elseecho "str1 is not equal to str2"
fi
3. 文件判断
用于判断文件的存在性、类型和权限。可以使用 -e
、-f
、-d
、-r
、-w
、-x
等操作符。
操作符 | 含义 |
---|---|
-e | 文件存在 |
-f | 文件存在且是普通文件 |
-d | 文件存在且是目录 |
-r | 文件存在且可读 |
-w | 文件存在且可写 |
-x | 文件存在且可执行 |
示例:
#!/bin/bash
file="/path/to/file"if [ -e "$file" ]; thenecho "File exists"if [ -r "$file" ]; thenecho "File is readable"fiif [ -w "$file" ]; thenecho "File is writable"fiif [ -x "$file" ]; thenecho "File is executable"fi
elseecho "File does not exist"
fi
4. 逻辑操作符
可以通过 &&
和 ||
将多个条件组合在一起进行判断。
操作符 | 含义 |
---|---|
&& | 逻辑与 |
|| | 逻辑或 |
! | 逻辑非 |
示例:
#!/bin/bash
num1=10
num2=20if [ $num1 -lt $num2 ] && [ $num1 -gt 5 ]; thenecho "num1 is less than num2 and greater than 5"
fiif [ -z "$str1" ] || [ -n "$str2" ]; thenecho "str1 is empty or str2 is not empty"
fi
5. 综合示例
示例:判断输入的文件是否为可读、可写且可执行的普通文件
#!/bin/bash
echo "Please enter a file path:"
read fileif [ -e "$file" ]; thenif [ -f "$file" ]; thenecho "$file is a regular file."if [ -r "$file" ] && [ -w "$file" ] && [ -x "$file" ]; thenecho "$file is readable, writable, and executable."elseecho "$file does not have all permissions (read, write, execute)."fielseecho "$file is not a regular file."fi
elseecho "$file does not exist."
fi
6. test
命令
在 Shell 脚本中,test
命令与 []
等效。可以直接使用 test
进行条件判断。
示例:
#!/bin/bash
num1=10
num2=20if test $num1 -lt $num2; thenecho "num1 is less than num2"
fi
通过这些条件判断,可以有效控制 Shell 脚本的执行流程。
** 流程控制**
Shell 脚本中有多种流程控制语句,用于控制代码执行的流程。这些包括条件语句、循环语句和分支选择。以下是常用的流程控制语句及其示例:
1. 条件语句
1.1 if
语句
if
语句用于条件判断,根据判断结果执行不同的代码。
语法:
if 条件; then# 条件为真时执行的代码
elif 另一个条件; then# 条件不满足时执行的代码
else# 条件不满足时执行的代码
fi
示例:
#!/bin/bash
num=10if [ $num -gt 5 ]; thenecho "num is greater than 5"
elif [ $num -eq 5 ]; thenecho "num is equal to 5"
elseecho "num is less than 5"
fi
注意:条件语句中的条件通常使用
[]
或test
命令来实现。
1.2 case
语句
case
语句适用于多个条件的判断,特别是在多分支选择时。
语法:
case 变量 in模式1)# 当变量匹配模式1时执行的代码;;模式2)# 当变量匹配模式2时执行的代码;;*)# 当没有匹配模式时执行的代码;;
esac
示例:
#!/bin/bash
fruit="apple"case $fruit in"apple")echo "It's an apple";;"banana")echo "It's a banana";;*)echo "Unknown fruit";;
esac
2. 循环语句
2.1 for
循环
for
循环用于遍历列表或范围内的每一项。
语法:
for 变量 in 列表; do# 每次循环执行的代码
done
示例:
#!/bin/bash
for i in 1 2 3 4 5; doecho "Number: $i"
done
特殊变量 $* 和 $@ ,字符串的时候‘*’整体,‘@’ 每个参数区分对待
- 基本语法:
$*
:这个变量代表命令行中所有的参数,把所有的参数看成一个整体
。$@
:这个变量也代表命令行中所有的参数,不过 $@ 把每个参数区分对待
。
#!/bin/bashecho '---$*---'
for i in $*; doecho "开启$i的软件服务"
doneecho '---$@---'
for i in $@; doecho "开启$i的软件服务"
done
这个脚本的主要功能是遍历命令行参数,并输出每个参数对应的“开启的软件服务”信息。
$*
和$@
都表示传递给脚本的所有命令行参数。for i in $*; do
和for i in $@; do
分别使用$*
和$@
来迭代所有参数。- 每个参数都会被打印出来,格式为:“开启的软件服务”。
注意:
$*
和$@
在处理多个空格分隔的参数时有所不同。在某些情况下,它们可能会有不同的行为,尤其是在参数包含特殊字符或空格的情况下。
2.2 while
循环
while
循环在条件为真时不断执行代码块。
语法:
while 条件; do# 条件为真时执行的代码
done
示例:
#!/bin/bash
count=1while [ $count -le 5 ]; doecho "Count: $count"count=$((count + 1))
done
2.3 until
循环
until
循环在条件为假时执行代码块,条件为真时退出循环。
语法:
until 条件; do# 条件为假时执行的代码
done
示例:
#!/bin/bash
count=1until [ $count -gt 5 ]; doecho "Count: $count"count=$((count + 1))
done
3. 跳出循环的控制语句
3.1 break
break
用于提前退出循环。
示例:
#!/bin/bash
for i in 1 2 3 4 5; doif [ $i -eq 3 ]; thenbreakfiecho "Number: $i"
done
# 输出结果为 1 2
3.2 continue
continue
用于跳过当前循环,直接进入下一次循环。
示例:
#!/bin/bash
for i in 1 2 3 4 5; doif [ $i -eq 3 ]; thencontinuefiecho "Number: $i"
done
# 输出结果为 1 2 4 5
4. 流程控制综合示例
示例:
#!/bin/bash
# 检查一个输入的数字是否为奇数还是偶数,并输出1到该数字之间的所有偶数echo "Enter a number:"
read numberif [ $number -lt 1 ]; thenecho "Please enter a positive integer."exit 1
fiecho "Even numbers from 1 to $number are:"for i in $(seq 1 $number); doif [ $((i % 2)) -ne 0 ]; thencontinuefiecho "$i"
done
在这个示例中,使用了 if
条件判断、for
循环和 continue
控制流程,以便输出 1 到指定数字之间的所有偶数。
函数
自定义函数
在Shell脚本中,我们可以定义自定义函数,以便重用代码并提高脚本的可维护性。Shell脚本的函数定义非常简单,下面是相关语法和一些常见的技巧。
1. 基本语法
Shell中定义函数的基本语法如下:
[ function ] funname() {# 函数体(执行的操作)action;[ return int; ]
}
funname
:自定义的函数名称。()
:函数名称后面可以跟空括号,Shell不需要明确指定函数的参数类型。action
:函数执行的操作或命令。return int
:可选的返回值,通常用来指定函数的退出状态(返回一个整数值,0表示成功,其他值表示失败,范围是 0 到 255)。如果不需要返回值,return
可省略。
2. 经验技巧
-
(1) 函数声明位置:Shell脚本是逐行执行的,因此必须在调用函数之前先声明它。这与其他语言(如C语言、Java等)不同,这些语言通常会先编译再执行。在Shell中,如果在函数调用之前没有定义函数,脚本会报错。
-
(2) 函数返回值:在Shell中,函数的返回值通常通过
$?
获取,它表示函数的退出状态码。return
后跟的值应该是一个整数,通常用于指示函数是否成功(return 0
通常表示成功,非0表示失败)。- 如果没有显式的
return
,Shell会默认返回最后一条命令的退出状态。 return
后跟的数值范围是0到255。
- 如果没有显式的
3. 案例实操:计算两个输入参数的和
假设你想写一个Shell脚本来计算两个输入参数的和。我们可以通过自定义函数来实现。
步骤 1:创建并编辑脚本
首先,创建一个新的Shell脚本文件 fun.sh
,然后使用编辑器打开它。
touch fun.sh
vim fun.sh
步骤 2:编写脚本内容
在 fun.sh
中定义一个简单的函数来计算两个数的和,并输出结果。
#!/bin/bash# 自定义函数:计算两个数的和
add_numbers() {sum=$(( $1 + $2 )) # $1 和 $2 是传入的两个参数echo "The sum is: $sum"return 0 # 返回值0表示函数执行成功
}# 调用函数并传递参数
add_numbers 10 20 # 输出:The sum is: 30# 获取函数的返回值
add_numbers 15 25
result=$? # 获取函数的退出状态码
echo "Return status: $result" # 输出:Return status: 0
步骤 3:解释脚本内容
-
add_numbers
函数:这是一个简单的函数,接受两个参数($1
和$2
),并计算它们的和。计算结果存储在sum
变量中,最后通过echo
输出。 -
返回值:函数通过
return 0
返回一个整数值,这表示函数执行成功。如果不指定return
,函数将使用最后执行的命令的退出状态。 -
调用函数:函数通过
add_numbers 10 20
被调用,传入两个参数 10 和 20。 -
捕获返回值:
result=$?
获取了函数执行后的返回值。在这个例子中,由于return 0
,返回值是 0,表示函数成功执行。
步骤 4:执行脚本
在命令行中执行脚本:
chmod +x fun.sh # 赋予执行权限
./fun.sh # 执行脚本
输出:
The sum is: 30
The sum is: 40
Return status: 0
- 定义函数:在Shell中,函数可以通过
function funname()
或funname()
来定义。 - 返回值:函数返回值通常是通过
return
来指定的,return 0
表示成功,其他值表示失败,默认返回的是最后执行命令的退出状态(通过$?
获取)。 - 函数调用顺序:Shell脚本是逐行执行的,确保函数在调用之前定义。
这个脚本首先定义了一个名为func
的函数,该函数接受两个参数(在这里表示为 x x x和 y y y),然后将这两个参数相加得到它们的和。接着,脚本使用read
命令提示用户分别输入两个数字,并将这些数字存储在变量X
和Y
中。最后,脚本调用func
函数并将用户输入的两个数字作为参数传入,从而执行求和操作并输出结果。
#!/bin/bash# 定义一个名为func的函数
function func() {SUM=0 # 初始化SUM为0SUM=$(($1 + $2)) # 计算第一个参数和第二个参数的和并赋值给SUMecho "您输入的参数的个数是$#" # 输出参数的数量echo "$SUM" # 输出两数之和
}# 从用户那里读取两个数字
read -p "请输入x的值: " X
read -p "请输入y的值: " Y# 调用func函数并将X和Y传递给它
func $X $Y
cut
命令的使用
cut
是一个用于从文本文件或输入中提取部分内容的命令。它通常用于从每一行中提取字段或字符。
基本语法:
cut [选项] [文件]
常用选项:
-f
:指定要提取的字段(列)。字段是以分隔符(默认为制表符)划分的。-d
:指定字段的分隔符,默认为制表符 (\t
)。-c
:指定要提取的字符位置范围(按字符索引)。--complement
:提取不在指定范围内的部分(反向提取)。
常见用法示例
1. 按字段提取内容
默认情况下,cut
以制表符作为字段分隔符,提取指定的字段。
示例:提取文件的第 2 列
假设文件 data.txt
的内容如下:
name age city
John 28 NewYork
Alice 30 Paris
Bob 25 London
我们可以使用 cut
提取第二列(age
):
cut -f 2 data.txt
输出:
age
28
30
25
注意:在默认情况下,cut
使用制表符作为字段分隔符。如果字段分隔符不是制表符,你需要使用 -d
选项指定分隔符。
2. 指定自定义分隔符
如果文件的字段是以其他字符分隔的,比如逗号(,
),可以使用 -d
来指定分隔符。
示例:提取以逗号分隔的 CSV 文件的第一列
假设 data.csv
的内容如下:
name,age,city
John,28,NewYork
Alice,30,Paris
Bob,25,London
提取第一列(name
):
cut -d ',' -f 1 data.csv
输出:
name
John
Alice
Bob
3. 按字符位置提取
除了按字段提取外,cut
也可以按字符位置来提取指定的字符范围。
示例:提取前 5 个字符
假设文件 data.txt
的内容如下:
abcdefg
hijklmn
opqrst
提取每行的前 5 个字符:
cut -c 1-5 data.txt
输出:
abcde
hijkl
opqrs
4. 提取多个字段或字符
你可以通过指定多个字段来提取多个列。例如,提取第 1 和第 3 列:
cut -f 1,3 data.txt
或者指定多个字符位置:
cut -c 1-3,6-8 data.txt
5. 排除指定的字段
使用 --complement
选项可以提取不在指定字段或字符范围内的内容。例如,排除第 2 列和第 3 列:
cut -f 2,3 --complement data.txt
6. 使用管道将数据传递给 cut
cut
可以与其他命令结合使用,通过管道 (|
) 将输出传递给 cut
进行进一步处理。
示例:使用 ps
命令获取进程信息并提取 PID 和进程名
ps aux | cut -d ' ' -f 1,2
这将显示每个进程的用户名和进程ID(PID)。
7. 使用 grep
和 cut
查找和提取字段
cat cut.txt | grep user| cut -f 1
提取 $PATH
中的第三个路径:
echo $PATH | cut -d ":" -f 3
8. 使用 grep
和 cut
获取和处理网络接口的信息
使用ifconfig
和一些管道命令来获取和处理网络接口的信息。具体作用如下:
-
ifconfig ens33
:- 显示
ens33
网络接口的详细信息,如IP地址、子网掩码、广播地址等。 - 输出示例:
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.6.100 netmask 255.255.255.0 broadcast 192.168.6.255 inet6 fe80::20c:29ff:fe74:d38b prefixlen 64 scopeid 0x20<link> ether 00:0c:29:74:d3:8b txqueuelen 1000 (Ethernet) RX packets 2162 bytes 164887 (161.0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 809 bytes 104071 (101.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 显示
-
ifconfig ens33 | grep netmask
:- 使用
grep
过滤出包含netmask
的行,即显示网络接口的子网掩码。 - 输出:
inet 192.168.6.100 netmask 255.255.255.0 broadcast 192.168.6.255
- 使用
-
ifconfig ens33 | grep netmask | cut -d " " -f 2
:cut
命令将通过空格分割该行,并选取第二个字段(即子网掩码部分)。这将输出255.255.255.0
。
-
ifconfig ens33 | grep netmask | cut -d "i" -f 2 | cut -d " " -f 2
:- 这条命令逻辑上稍有问题。
cut -d "i" -f 2
会在每个i
字符处分割字符串,输出不符合预期的部分。实际应该是用空格作为分隔符,而不是i
字符。 - 如果正确执行目标,应该写成:
这样才会返回正确的子网掩码。ifconfig ens33 | grep netmask | cut -d " " -f 2
- 这条命令逻辑上稍有问题。
ifconfig
显示网络接口的详细信息;grep
过滤指定内容(例如,包含netmask
的行);cut
用来分割并提取需要的字段。
awk
的使用
awk
是一个强大的文本处理工具,用于处理格式化文本和生成报告。它特别擅长处理以空格或指定分隔符分隔的字段。awk
可以根据指定的模式对文本进行匹配,并对匹配的行执行相应的操作。
基本语法:
awk 'pattern {action}' filename
pattern
:用于匹配文本行的模式(可以是正则表达式)。如果省略,表示对所有行执行操作。action
:对匹配的文本执行的操作,通常是打印、计算、修改等。如果省略,awk
默认打印匹配的行。
awk
可以通过指定字段分隔符(如空格、制表符或自定义分隔符)来处理数据。
1. 基本用法:打印特定字段
默认情况下,awk
使用空格或制表符(\t
)作为字段分隔符。awk
将每一行分割成字段,并通过 $1
, $2
, …, $NF
来访问每个字段。
示例:打印每行的第一个字段(假设以空格分隔)
awk '{print $1}' filename
示例:打印每行的第二个字段
awk '{print $2}' filename
示例:打印每行的最后一个字段
awk '{print $NF}' filename
$NF
是awk
的一个内置变量,表示当前行的最后一个字段。
2. 使用指定的分隔符
默认情况下,awk
使用空格或制表符作为字段分隔符。如果数据使用其他分隔符(如逗号、冒号等),可以使用 -F
选项来指定分隔符。
示例:用逗号作为分隔符的 CSV 文件
假设 data.csv
文件的内容如下:
name,age,city
John,28,New York
Alice,30,Paris
Bob,25,London
打印每行的第一列(name
):
awk -F ',' '{print $1}' data.csv
输出:
name
John
Alice
Bob
3. 使用模式进行匹配
awk
可以根据模式来选择要处理的行。模式可以是正则表达式、条件表达式或内置条件。
示例:打印包含 “New York” 的行
awk '$3 == "New" && $4 == "York" {print $0}' data.csv
$0
代表当前整行。- 这会检查第三列和第四列是否分别为
"New"
和"York"
,如果匹配,则打印整行。
4. 内置变量
$1
,$2
, …,$NF
:表示当前行的各个字段。$0
:表示当前行的完整内容。NF
:当前行的字段数。NR
:已处理的行号(从 1 开始计数)。FS
:字段分隔符,默认为空格或制表符。OFS
:输出字段分隔符,默认为空格。
示例:打印行号和每行的内容
awk '{print NR, $0}' data.csv
输出:
1 name,age,city
2 John,28,New York
3 Alice,30,Paris
4 Bob,25,London
5. 条件语句
awk
支持常见的条件语句,如 if
、else
、while
等。
示例:打印年龄大于 28 的人
awk -F ',' '{if ($2 > 28) print $1}' data.csv
输出:
Alice
6. 数学计算
awk
支持数学运算,可以用于对字段进行计算、汇总等操作。
示例:计算所有人的年龄和
awk -F ',' '{sum += $2} END {print "Total age:", sum}' data.csv
输出:
Total age: 83
END
块表示在所有行处理完毕后执行的操作。这里,我们累加第二列的年龄,最后打印总和。
7. 格式化输出
awk
支持使用 printf
来格式化输出,类似于 C 语言中的 printf
。
示例:打印每个人的姓名和年龄,格式化输出
awk -F ',' '{printf "Name: %-10s Age: %-3s\n", $1, $2}' data.csv
输出:
Name: name Age: age
Name: John Age: 28
Name: Alice Age: 30
Name: Bob Age: 25
8. 输出到文件
可以将 awk
的输出重定向到文件中。
示例:将符合条件的行输出到新文件 output.txt
awk '$2 > 28' data.csv > output.txt
9. 多个命令的组合
awk
也支持多条操作命令,可以使用分号分隔。
示例:打印姓名和年龄,并同时计算总年龄
awk -F ',' '{print $1, $2; sum += $2} END {print "Total age:", sum}' data.csv
查找包含 mysql
的行并打印第一字段(用户名):
awk -F ":" '/mysql/ {print $1}' passwd
查找包含 mysql
的行并打印第二字段(密码):
awk -F ":" '/mysql/ {print $2}' passwd
查找包含 mysql
的行并打印第三字段(UID):
awk -F ":" '/mysql/ {print $3}' passwd
提取 IP 地址:
ifconfig ens33 | awk '/inet/ {print $2}'
提取 netmask:
ifconfig ens33 | awk '/netmask/ {print $4}'
提取默认网关:
ifconfig | awk '/default/ {print $2}'
sort
的使用
1. sort
命令
sort
用于对文本文件或标准输入的数据进行排序。默认情况下,sort
按照字典顺序进行升序排序。
基本语法:
sort [选项] [文件]
常见选项:
-r
:反向排序,按降序排列。-n
:按数字排序(而非字典顺序)。-k
:指定排序的字段或列。-u
:去除重复行,只保留一个。-t
:指定分隔符(用于按字段排序)。
例子:
-
按字典顺序排序文件内容:
sort filename.txt
-
按降序排序文件内容:
sort -r filename.txt
-
按数字排序文件(例如排序 IP 地址或数字列表):
sort -n numbers.txt
-
按指定字段排序(按第 2 列排序):
sort -k2 filename.txt
-
按分隔符(例如逗号)排序指定字段:
sort -t, -k2 filename.csv
-
去除重复行并排序:
sort -u filename.txt
wc
命令
wc
(word count)用于统计文本的行数、字数和字符数。它非常适用于统计文件的基本信息。
基本语法:
wc [选项] [文件]
常见选项:
-l
:统计行数。-w
:统计单词数。-c
:统计字节数(字符数)。-m
:统计字符数(与字节数类似,但对多字节字符(如 UTF-8)可能有所不同)。-L
:显示文件中最长行的长度。
例子:
-
统计文件的行数、字数和字符数:
wc filename.txt
输出类似于:
10 50 400 filename.txt
其中:
10
:文件的行数。50
:文件的单词数。400
:文件的字符数。
-
仅统计文件的行数:
wc -l filename.txt
-
仅统计文件的单词数:
wc -w filename.txt
-
仅统计文件的字符数:
wc -c filename.txt
-
统计多个文件的行数、字数和字符数:
wc -l file1.txt file2.txt
-
统计最长行的字符数:
wc -L filename.txt