Shell 指令
- 什么是shell:shell本质是用户与操作系统之间的交互界面。它既是一个命令行解释器,也是一个脚本语言。
- 作用:Shell 是用户与操作系统内核(Kernel)之间的桥梁。它允许用户通过命令行或脚本与操作系统进行交互,执行各种任务,如文件管理、程序运行、系统配置等。
一、基础操作指令
1.1 文件操作
- 文件类型标识:
bcd-lsp
(普通文件、块设备、字符设备、目录、符号链接、套接字、管道) - 常用命令:
`ls`:查看目录内容(`-l`显示详情,`-h`友好单位,`-a`显示隐藏文件) `chmod`:修改权限(`rwx`对应421) `touch`:创建文件 `mkdir`:创建目录 `rm`:删除(`-r`递归删除目录) `cat`:打印文件内容
1.2 重定向与管道
- 操作符:
> # 覆盖重定向(例:echo "hello" > file.txt) >> # 追加重定向(例:echo "world" >> file.txt) | # 管道符(例:cat file.txt | grep "error")
1.3 文件操作
- 复制与移动:
`cp -r dir1 dir2` # 递归复制目录 `mv old.txt new.txt` # 重命名文件 `mv file.txt /target` # 移动文件
二、虚拟机网络配置
2.1 网络连接检查
```bash
`ping www.baidu.com` #测试网络连通性
`ifconfig` #(Ubuntu)查看IP地址
`ipconfig` #(Windows)查看IP地址
```
2.2 网络模式
- 桥接模式:Ubuntu与主机独立IP(适用于网络编程)
- NAT模式:共享主机IP(默认推荐)
- 主机模式:仅主机与虚拟机通信,无外网
2.3 IP地址查看
- Ubuntu:
ifconfig
中inet
字段 - Windows:
ipconfig
中IPv4地址
三、在线下载(APT)
- 软件源配置
- 替换为国内源(清华、阿里等)
- 备份并编辑
/etc/apt/sources.list
- 替换后更新:
sudo apt-get update
- 软件管理
- 安装:
sudo apt-get install 软件名
- 卸载:
sudo apt-get remove 软件名
(保留配置) - 彻底卸载:
sudo apt-get purge 软件名
- 下载安装包:
sudo apt-get download 软件名
- 清理缓存:
sudo apt-get clean
- 安装:
四、离线安装(DPKG)
-
安装包格式
.deb
(Ubuntu)与.rpm
(Red Hat)
-
命令操作
- 安装:
sudo dpkg -i 安装包.deb
- 卸载:
sudo dpkg -P 软件名
(删除配置) sudo dpkg -r 软件名
(不删除配置)
- 安装:
-
依赖问题
- 离线安装需手动解决依赖(在线自动处理)
五、文件处理指令
- 内容查看
head -n 文件名
:显示前n行,(默认10行)tail -n 文件名
:显示后n行,(默认10行)
- 搜索与过滤
find 路径 -name "模式"
(支持通配符*
,?
和[]
)grep "模式" 文件
:查找字符串在文件中的位置(支持正则表达式)
- 文本处理
cut -d分隔符 -f字段
(剪切字符串)wc
统计行/词/字符数(-l
行,-w
词)
- 权限与属性
chgrp
修改文件所属组chown
修改文件所有者
六、链接文件ln
- 硬链接文件
ln 源文件名 链接文件名
- 硬链接文件是普通文件(
-
) - 硬链接文件的inode值相同
- 修改任意硬链接文件内容,其余文件内容也改变
- 目录文件无法创建硬链接
- 软连接
ln -s 源文件绝对路径 链接文件绝对路径
- 软连接文件的文件类型是链接文件
l
- 软链接文件的inode值不同
- 修改任意硬链接文件内容,其余文件内容也改变
- 删除源文件后相同路径创建同名文件,链接关系重新生效
- 允许目录文件创建软链接
七、压缩/解压/归档/拆包
- 压缩
xz 文件名
:生成一个*.xz
压缩包bzip2 文件名
:生成一个*.bz2
压缩包gzip 文件名
:生成一个*.gz
压缩包
- 解压
unxz 文件名
bunzip2 文件名
gunzip 文件名
- PS:
- 压缩效率:
xz > bzip2 > gzip
- 压缩时间:
xz > bzip2 > gzip
- 压缩后原文件会被删除
- 压缩效率:
- 归档/拆包
tar -cvf *.tar 目标文件/目录
:归档不会删除原文件tar -xvf *.tar 目标文件/目录
:解包-
-c
:归档
-
-x
:解包
-
-C
:解包到目标目录
-
-v
:显示过程
-
-f
:操作文件
-
-J/-j/-z
:归档并压缩xz/bz2/gz
(解包时可以不加)
八、用户管理
- 信息查看
whoami
:查看用户id
:查看用户id
- 用户切换
sudo su 用户名
:切换用户exit
:退出当前用户sudo passwd 用户名
:修改用户密码
- 创建用户
sudo useradd 用户名
:把用户添加到/etc/passwrod文件sudo adduser
:使用模板创建一个新用户
- 删除用户
sudo userdel 用户名
:只从/etc/passwrod删除用户,不删除家目录sudo deluser 用户名
:从系统删除用户和模板,不删除家目录sudo userdel 用户名 -r / sudo deluser 用户名 --remove-home
:删除用户并删除家目录
- 权限及信息修改
sudo vim etc/sudoers
:添加用户sudo权限(用户名 ALL=(ALL) ALL
)usermod -l 新用户名 用户名
:修改用户名usermod -c 描述信息 用户名
:修改用户描述信息usermod -m -d 新目录 原名字
:修改用户家目录
- 组操作
groupadd 组名
:创建一个新的组,组文件/etc/group
addgroup 用户名 组名
:将用户添加到组groupdel 组名
:删除一个组delgroup 用户名 组名
:将用户从组中删除
九、电源指令
- shutdown
shutdown 10
:10分钟后关机shutdown 10:00
:10点关机shutdown now
:立刻关机-
--show
:显示关机动作和时间
-
-r
:重启
-
-c
:取消关机
十、磁盘指令
- 磁盘信息查看
df /dev/**
:查看/dev/**
的使用情况-
-lh
:查看磁盘的情况,单位KMG
-
-a
:查看磁盘的情况,显示大小为0的
- 挂载
mount 磁盘分区 挂载点
:将磁盘挂载到挂载点umount 挂载点
:取消挂载
- 磁盘操作
fdisk 物理磁盘路径
:对磁盘进行分区等操作mkfd.格式 分区路径
: 用目标格式格式化磁盘
十一、shell script脚本
11.1 解释器
- 常见的解释器:
bash/sh/dash/csh/ksh
-
echo &SHELL
/cat /etc/shells
:查看解释器
- shell脚本
vim *.sh
:创建shell脚本- shell脚本通常是以一个#!起始的文本文件如下
#!/bin/bash
shebang
特殊行,在这行中字符#!
被置于解释器路径之前,/bin/bash
是解释器Bash
的路径- 使用
bash *.sh
或source *.sh
或./*.sh
运行脚本文件(运行前需要修改文件权限,赋予可执行权限)
- 快速执行环境配置
- 可以使用
env
命令查看环境变量 - 打开
~/.bashrc
文件配置环境变量export PATH=$PATH:/…… #让目标路径下的shell脚本可以在终端使用文件名快速执行,修改仅对当前用户有效
- 打开
/etc/bash.bashrc
文件配置环境变量export PATH=$PATH:/…… #让目标路径下的shell脚本可以在终端使用文件名快速执行,修改仅对所有用户有效
- 打开
/etc/environment
文件配置环境变量#在目标文件的PATH变量后添加指定路径,用':'分割 #让目标路径下的shell脚本可以在终端使用文件名快速执行,修改仅对所有用户有效
- 可以使用
11.3 debug
方法
-
使用解释器的选项来确认语法错误,这里以
bash
为例子 -
使用解释器内置的选项来调试
bash [-nvx] scripts.sh
-
选项
-n
不要执行,仅仅输出语法问题-v
先输出脚本内容-x
将使用到的script先输出到屏幕上
-
在脚本中指定调试段落
#!/bin/bash set -x echo "开始调试" # 调试代码 set +x echo "结束调试"
-
使用调试器(类似gdb)
apt-get install bashdb bashdb script.sh
11.4 内置命令type
-
type [-tpa] name
- 选项:
- 不加任何选项与参数时,type 会显示出 name 是外部指令还是 bash 内置指令
-t
当加入 -t 参数时,type 会将 name 以下面这些字眼显示出他的意义:- file :表示为外部指令;
- alias :表示该指令为命令别名所设置的名称;
- builtin :表示该指令为 bash 内置的指令功能;
-p
如果后面接的 name 为外部指令时,才会显示完整文件名;-a
会由 PATH 变量定义的路径中,将所有含 name 的指令都列出来,包含 alias
- 选项:
11.5 shell变量
-
shell变量是没有数据类型的,默认为字符串类型,且默认为全局变量
-
shell变量对操作环境会造成影响,如上文中的
PATH
变量,其决定了你能不能在任何目录下执行某个指令。例如使用ls时系统就是通过PATH
变量中的路径来搜索指令的。 -
变量定义及初始化:
variabl=hello #variabl指定义的变量名 variabl= #注意书写赋值语句`=`两边不能有空格 variabl="hello world" #当赋值中存在空格时需要使用双引号或者单引号 variabl='hello world' #单引号中的字符仅为一般字符串 #双引号中的特殊字符可以保留其原本特性 variabl_1=$variabl #使用变量进行赋值时需要用'$'符号
-
- 在Linux环境中,使用{大写字母}设定的变量一般是系统内定需要的变量
-
位置变量:
$n #类似于c语言mian函数的argv,其$0中会存储文件名 $@ #表示所有位置参数,每个参数保持独立(即使包含空格) $* #表示所有位置参数,所有参数整合为一个字符串,用空格分隔 $# #表示参数个数 $$ #获取当前shell的PID $? #获取上一个指令的执行结果,成功返回0,失败返回非0错误值
-
输入/输出变量内容:
#输出 echo ${变量} echo $变量 echo hello world echo -n #不输出换行符 echo -e #允许用转义字符 #输入 #使用read进行输入时可以用空格或tab对输入值进行分隔,若输入换行则结束输入 read a b c #可以一次性对多个变量进行定义并赋值 read -p #显示提示信息 read -n #输入变量字符数 read -t #定时输入 read -a #输入类型为阵列(数组) read -s #加密输入
-
特殊符号
unset variabl #取消变量 readonly variabl #设置变量为只读,无法修改值且无法取消 local variabl #局部变量 export variabl #将变量转变为环境变量,使其可以在子程序中使用
-
指令输出转换
#在想使用指令的输出值进行赋值等操作时可以使用反单引号或$(指令) a=`指令` a=$(指令)
-
字符操作:
${#string} #计算字符长度 string=$str1$str2 #将str1和str2两个字符拼接赋值给string #字符串截取 ${string:m} #从左往右,截取第m个后的所有字符 ${string:m:n} #从左往右,截取第m个后的n个字符 ${string:0-m} #从右往左,截取第m个后的所有字符 ${string:0-m:n} #从右往左,截取第m个后的n个字符 ${string#*/} #从左往右,截取第一个'/'后的所有内容 ${string##*/} #从左往右,截取最后一个'/'后的所有内容 ${string%*/} #从右往左,截取第一个'/'后的所有内容 ${string##*/} #从右往左,截取最后一个'/'后的所有内容
-
shell数组:
#数组定义 arr={1 2 3 hello world} #稀疏数组 arr[0]=1 arr[4]=2 #sehll支持稀疏数组,该数组就含2个元素 #数组拼接 c=(${a[@]}${b[@]}) c=(${a[*]}${b[*]}) #使用${arr[@]}或${arr[*]}可以输出/获取全部数组元素 #数组长度 ${#arr[@]} ${#arr[*]}
11.6 sehll运算
-
-shell中数据默认为字符串类型,擅长字符串,文件等操作
((c=a+b)) c=$((a+b)) c=$[a+b] let c=a+b #以上三种运算方式都支持任意整数运算
expr
指令
- 在 Bash 中,
expr
是一个非常有用的命令,用于进行算术运算、字符串操作和逻辑判断。以下是expr
的主要用法和一些示例:
算术运算:expr
可以执行基本的算术运算,包括加法、减法、乘法、除法和取模。
算术运算符
-
运算符 说明 示例 输出 +
加法 expr 5 + 3
8
-
减法 expr 5 - 3
2
*
乘法 expr 5 \* 3
15
/
除法 expr 5 / 3
1
%
取模(余数) expr 5 % 3
2
-
注意:乘法运算符
*
需要用反斜杠\
转义,否则会被 Shell 误认为是通配符。
字符串操作
expr
可以对字符串进行操作,包括匹配、截取和比较。
字符串操作符
-
运算符 说明 示例 输出 match
匹配字符串 expr "abc123" : 'abc\([0-9]*\)'
123
index
查找字符在字符串中的位置 expr index "abc123" '1'
4
substr
截取字符串 expr substr "abc123" 4 3
123
length
获取字符串长度 expr length "abc123"
6
-
注意
match
时尽量加括号,否则返回的是则会返回匹配的字符的个数,若没有匹配则返回 0
逻辑判断
expr
可以进行逻辑判断,返回值为 0
(假)或 1
(真)。
逻辑运算符
-
运算符 说明 示例 输出 =
判断是否相等 expr 5 = 3
0
!=
判断是否不相等 expr 5 != 3
1
<
判断是否小于 expr 5 < 3
0
<=
判断是否小于等于 expr 5 <= 3
0
>
判断是否大于 expr 5 > 3
1
>=
判断是否大于等于 expr 5 >= 3
1
关系运算
expr
还支持布尔运算,包括逻辑与(&
)、逻辑或(|
)和逻辑非(!
)。
关系运算符
-
运算符 说明 示例 输出 &
逻辑与 expr 1 = 1 & 2 = 2
1
` ` 逻辑或 `expr 1 = 1 !
逻辑非 expr ! 1 = 1
0
注意事项
- 空格:
expr
的参数之间必须有空格,否则会报错。 - 转义:某些特殊字符(如
*
和&
)需要用反斜杠\
转义。 - 整数运算:
expr
只支持整数运算,不支持浮点数。 - 输出格式:
expr
的输出是字符串,而不是数字。
test
指令
test
命令用于检查文件属性、字符串、数字等条件,通常在shell脚本中使用。它有两种写法:`test expression` `[ expression ]`
test
命令可以检查文件的存在性、类型和权限等。#两种写法等价 #检查文件是否存在 test -e /path/to/file [ -e /path/to/file ] #检查是否为普通文件 test -f /path/to/file #检查是否为目录 test -d /path/to/directory #检查文件权限 test -r /path/to/file test -w /path/to/file test -x /path/to/file
test
命令可以检查字符串的长度和内容。#检查字符串是否为空 test -z "string" #检查字符串是否非空 test -n "string" #检查两个字符串是否相等 test "str1" = "str2"
test
命令可以对整形数字进行关系运算test $a -gt $b # 大于 test $a -lt $b # 小于 test $a -eq $b # 等于
11.7 控制语句
判断
if
判断
if [ 判断条件 ]
then
语句
if [ 判断条件 ] ; then
语句
elif [判断条件] ; then
语句
else
语句
fi
语句
fi
#注意在判断符号之后需要有分号`;`,否则then需要换行
#判断条件里不能写`$(())`,只能写`(())`和`()`
case in
判断
case ${变量} in
"字符串1")
语句;;
"字符串2"|"字符串3")
语句;;
*) #default
语句;;
esac
#使用 `|` 来连接多个匹配项
#使用 `;;` 来跳过后续的匹配
#可以使用通配符来匹配值
循环
while [condition] #条件成立时进循环
do
程序
done
until [condition] #条件不成立时进循环
do
程序
done
select var in 迭代器 #请注意这里会把var的值赋值成迭代器里的某个值,交互式cli用的
do #运行后需要使用`ctrl+c`或`ctrl+d`退出循环
程序
done
# for循环的两种写法
for var in 迭代器
do
程序
done
for ((i=1;i<=$1>;i++))
do
程序
done
循环跳转
break n #跳出n层循环
#n为1时可以省略
continue n #结束n次循环,进入n+1次循环
#n为1时可以省略
11.8 函数
函数定义
#shell函数格式
funtion aa()
{
函数体
}
funtion aa
{
函数体
}
aa()
{
函数体
}
#调用
aa
#sehll函数定义时 funtion 和 () 可以省略其一
#()仅代表函数,不允许添加参数
#函数调用后无需加()
函数传参
#sehll函数传参需要借助位置变量和预定义变量 `$n $* $@ $#`
funtion 函数名()
{
$0 #文件名
$1 #参数1
$2 #参数2
$@ #所有参数
$* #所有参数
$# #参数个数
}
函数名 参数1 参数2 参数3 ……
函数返回
- Bash 函数的返回值本质是一个 退出状态码(范围 0-255),通过 return 或函数最后一条命令的退出状态决定:
return返回
function check_file() {
if [ -f "$1" ]; then
return 0 # 文件存在,返回成功
else
return 1 # 文件不存在,返回失败
fi
}
check_file "/etc/passwd"
echo "Status: $?" # 输出上一个命令的退出状态码(0 或 1)
#隐式返回最后一条命令的状态
function is_user_root() {
[ "$(id -u)" -eq 0 ] # 检查是否为 root 用户,最后一条命令的退出状态决定返回值
}
is_user_root
echo "Is root? $?" # 0=是root,1=不是
通过标准输出返回
- 若需返回字符串、数字等复杂数据(而非状态码),需通过 echo 或 printf 输出结果,调用者用 $(…) 或反引号捕获
#返回字符串
function get_date() {
echo "Today is $(date)"
}
result=$(get_date) # 捕获函数的输出
echo "$result" # 输出:Today is Fri Apr 12 10:00:00 UTC 2024
#返回多个值
function parse_url() {
local url="$1"
echo "${url%%/*}" # 返回协议(如 http:)
echo "${url##*/}" # 返回路径最后一部分
}
read -r protocol path <<< "$(parse_url "http://example.com/path")"
echo "Protocol: $protocol, Path: $path"
结合返回
- 若需同时返回状态码和数据,可通过以下方式:
function process_data() {
local input="$1"
if [ -z "$input" ]; then
echo "Error: Input is empty" >&2 # 错误信息输出到 stderr
return 1
else
echo "${input^^}" # 转换为大写并输出到 stdout
return 0
fi
}
output=$(process_data "hello")
if [ $? -eq 0 ]; then
echo "Processed: $output" # 输出:Processed: HELLO
else
echo "Failed to process."
fi
注意事项
-
- 作用域限制:函数内定义的局部变量需用 local 声明,否则会污染全局作用域。返回值无法直接返回数组或复杂对象,需通过字符串拼接或全局变量传递。
-
- 捕获输出的陷阱:若函数内有其他 echo 语句(如日志),会被一并捕获,建议错误信息输出到 stderr(>&2)。
-
- 状态码范围:return 的值必须在 0-255 之间,超出会取模(如 return 256 实际返回 0)。