Shell | 命令、编程及Linux操作系统的基本概念

前面结束了数据结构的相关内容,我们又得继续下一个内容的学习,也就是Linux软件编程,这一部分的内容也相对较多,需要循序渐进的学习,那就跟着博主一起来学吧:

1、操作系统基本概念

操作系统可以看成是一个软件,功能是用来屏蔽底层不同的硬件平台,为上层应用提供统一的接口和运行环境

操作系统类型:

|---------|--------------------------|
| Unix | 经典老牌,现代 OS 鼻祖 |
| Linux | 高效运行、开源免费,内核基于 Unix 思想开发 |
| Windows | 视窗界面友好 |

**Linux应用领域:**服务器、嵌入式领域、机器人、Android手机、平板、广告机、视频记录仪、路由器、交换器等

(1)Linux内核---功能:

  • 内存的管理
  • 文件系统的管理
  • 任务的调度 //FreeRTOS实现的功能
  • 多任务的通信
  • 网络功能的管理
  • 对硬件设备的管理

(2)Shell:

1、保护内核,用户不直接操作内核,所有请求都通过 Shell 中转,避免用户直接调用内核接口引发系统崩溃

2、命令行解释器 :是用户与内核之间的交互接口,读取解析用户命令并转化为对系统调用或可执行程序的调用请求 → 传递请求给内核→ 内核直接执行指令(直接执行其早已编译好的二进制代码(最初由C等语言编写))

(3)库函数:

1、库函数是**封装好的可复用代码集合,**便于用户函数调用

2、简化开发

系统调用是内核提供的底层接口,语法繁琐、平台差异大;库函数对其封装,提供简洁统一的调用接口,比如用printf打印,无需直接操作底层的系统调用

3、跨平台兼容性(便于移植)

同一套标准库函数可以在 Windows、Linux、macOS 编译运行,底层适配不同系统的系统调用,开发者无需关注平台差异。

2、Shell命令

2.1 命令格式

bash 复制代码
command [options] [arguments]

options:选项,用于调整命令行为,短选项用-开头(如-n),长选项用--开头(如--help),多个短选项可合并(cat -n -v = cat -nv)
 
arguments:参数,命令操作的对象(如文件名、路径、字符串),是可选部分

格式中[]代表可选内容,不是命令的一部分,输入时无需书写

2.2 常用命令

2.2.1 文件查看命令

(1)cat

功能: 查看文件全部内容(查看小型文本文件更适合

bash 复制代码
cat filename # 查看文件全部内容

cat -n filename # 显示行号(包含空行)

cat -b filename # 显示行号(跳过空行)

(2)head/tail

功能:head 查看文件开头内容,tail查看文件末尾内容, 默认显示10行

bash 复制代码
head -n 10 filename # 查看文件前10行(-n可省略,直接写 head -10 filename)

tail -n 10 filename # 查看文件后10行

tail -f filename # 实时追踪文件新增内容(查看日志必备,如服务运行日志)

2.2.2 管道符 |

功能:将前一个命令的标准输出,作为后一个命令的标准输入,实现命令组合

bash 复制代码
# 筛选文件前10行中包含指定字符串的内容

head -n 10 filename | grep "字符串"

# 筛选头文件末尾10行中包含extern的内容

tail -n 10 /usr/include/stdio.h | grep "extern"

# 查看系统中与bash相关的进程信息

ps -ef | grep bash

注意:管道仅传递标准输出 (stdout),错误信息 不会通过管道传递

2.2.3 文件搜索命令---grep

功能:在文件 / 输入流中按规则搜索字符串 / 正则表达式,输出匹配行

bash 复制代码
# 在指定文件中搜索字符串

grep "目标字符串" 文件名

 

grep -i "字符串" filename # 忽略大小写搜索

grep -v "字符串" filename # 反向匹配,输出不包含该字符串的行

grep -n "字符串" filename # 显示匹配行的行号

grep -c "字符串" filename # 仅统计匹配的行数

2.2.4 重定向

功能: Shell 默认将输出打印到终端(标准输出),重定向可将输出写入文件 / 其他设备,分为输出重定向和输入重定向 将原来输出在终端的内容写入到文件中

输出重定向
符号 作用 示例
> 覆盖重定向 若文件不存在则创建,存在则清空原有内容后写入
>> 追加重定向 若文件不存在则创建,存在则在文件末尾追加内容
bash 复制代码
echo "hello" > test.txt # 覆盖写入test.txt

echo "world" >> test.txt # 追加内容到test.txt

输入重定向( < )

bash 复制代码
# 正常方式:grep从文件读取
grep "error" log.txt

# 输入重定向方式:功能完全一样!
grep "error" < log.txt

2.2.5 通配符

功能: 用于匹配文件名 / 路径,配合 ls、rm、cp 等文件操作命令使用

通配符 含义 示例
* 匹配任意长度、任意字符(包含空字符) ls *.txt 匹配所有 txt 文件
? 匹配单个任意字符 ls file?.txt 匹配 file1.txt、filea.txt
[] 匹配括号内任意一个字符 ls file[123].txt 仅匹配 file1/2/3.txt
[^] 匹配不在括号内的单个字符 ls file[^0-9].txt 排除数字命名文件

注意 :通配符是 Shell 解析的,不是命令自身功能

2.2.6 文件权限管理

(1)权限基础规则

Linux 文件权限分三类用户:

  • 属主 (u):文件的创建者 / 所有者
  • 属组 (g):文件所属用户组的成员
  • 其他用户 (o):系统内除 u、g 外的所有用户

权限对应符号与数字权重:

权限 符号 数字权重 含义
r 4 读取文件内容 / 查看目录结构
w 2 修改文件内容 / 在目录内增删文件
执行 x 1 执行脚本 / 进入目录

权限组合计算:rwx=4+2+1=7rw-=6r-x=5---=0

(2)修改文件 / 目录权限:chmod

bash 复制代码
chmod 0777 filename
# 三位数字依次对应:属主、属组、其他用户 权限
# 0为特殊权限位,日常使用可省略,直接写 chmod 755 filename

chmod u+x filename   # 给属主添加执行权限
chmod g-w filename   # 给属组移除写权限
chmod a=r filename   # 所有用户(u/g/o)统一设置为只读权限

#加-R选项递归修改目录下所有子文件 / 子目录权限,包括目录自身
chmod -R 755 test_dir/

rwx:创建文件的用户对文件是否拥有读写执行的权限

rwx:创建文件的同组用户对文件是否拥有读写执行的权限

rwx:其余人是否拥有读写执行的权限

(3)修改文件所属的组:chgrp

bash 复制代码
# 查看所有组
cat /etc/group

sudo chgrp 组名 filename  # 修改文件所属组,组必须存在

chown:

(4)chown:修改文件所属的用户 ,同时可修改所属组

**功能:**同时支持修改属主和属组,比chgrp更通用

bash 复制代码
chown 用户名 filename        # 仅修改文件属主,也必须存在
chown 用户名:组名 filename   # 同时修改属主和属组(常用)

2.2.7 压缩和解压缩

(1) 核心参数释义

参数 作用
-c create,创建归档 / 压缩包(压缩必备)
-x extract,解压归档 / 压缩包(解压缩必备)
-v verbose,显示压缩 / 解压的详细过程(可选,方便查看进度)
-f file,指定压缩包文件名,必须放在所有参数最后一位
-z 调用gzip算法,对应.tar.gz/.tgz格式
-j 调用bzip2算法,对应.tar.bz2/.tbz格式

(2) 压缩命令

bash 复制代码
# 压缩为 .tar.gz 格式(gzip,压缩速度快,使用率最高)
tar -zcvf filename.tar.gz dirname/
# 压缩为 .tar.bz2 格式(bzip2,压缩率更高,速度稍慢)
tar -jcvf filename.tar.bz2 dirname/

tar -zcvf /target/archive.tar.gz source/	压缩到指定目录,直接指定输出文件路径

注意:

dirname/* 可简化为 dirname/,效果一致,会打包目录下所有文件;

-f 参数必须紧跟压缩包名称,不能穿插其他参数

(3)解压缩命令

bash 复制代码
# 解压 .tar.gz 格式
tar -zxvf filename.tar.gz
# 解压 .tar.bz2 格式
tar -jxvf filename.tar.bz2

# 解压到指定目录(-C 参数,大写C)
tar -zxvf filename.tar.gz -C /home/test/

2.2.8 查找文件---find

bash 复制代码
find [搜索起始目录] [匹配条件] "文件名"


# 精确查找文件(区分大小写)
find /home -name "test.txt"
# 忽略大小写查找(-iname,更常用)
find /home -iname "TEST.txt"
# 结合通配符模糊查找
find /etc -name "*.conf"  # 查找所有.conf后缀配置文件


find /home -type f  # 只查找普通文件,排除目录
find /home -type d  # 只查找目录
find /home -size +100M  # 查找大于100MB的文件 100k(小写)
find /home -mtime -7  # 查找7天内修改过的文件

2.2.9 其余命令

(1)echo:

功能:在终端输出字符串、变量值,配合重定向可快速写入文件;在终端显示对应内容

bash 复制代码
echo "Hello Linux"  # 输出固定字符串
echo $PATH          # 输出系统环境变量PATH的值

echo -n "无换行输出"  # -n:取消末尾自动换行
echo "追加内容" >> test.txt  # 结合追加重定向写入文件

(2)du:

功能 :disk usage,统计文件 / 目录的磁盘占用大小

bash 复制代码
du -h  # 人性化显示单位(KB/MB/GB,最推荐使用)
du -m  # 以MB为单位显示大小
du -k  # 以KB为单位显示大小
du -sh dirname/  # 统计目录总大小,不展示子文件详情(高频用法)

(3)fdisk :

功能 :查看磁盘分区信息,仅 root / 授权用户可执行

bash 复制代码
sudo fdisk -l  # 列出系统所有磁盘及分区信息(含容量、格式、挂载点)

(4)sudo:

功能 :switch user and do,临时以超级用户(root)权限执行命令,避免长期使用 root 账户带来风险

使用超级用户的权限来执行某个操作

bash 复制代码
sudo [需要提权的命令]

示例:sudo vim /etc/hosts(修改系统配置文件需要提权)

(5)date:

功能:查看 / 设置系统日期和时间

bash 复制代码
date  # 查看当前系统时间(默认格式)

date "+%Y-%m-%d %H:%M:%S"  # 自定义格式:年-月-日 时:分:秒

(6)whoami :

功能 :快速查看当前登录终端的用户名

bash 复制代码
whoami

(7)ps:
功能 :process status,查看当前系统进程信息(静态查看,执行一次输出一次结果)

bash 复制代码
ps -ef  # 查看系统所有进程完整信息(含PPID父进程ID、用户、命令等)
ps aux  # BSD格式展示进程,是Linux下更通用的写法,展示内容更全面

(8)top:

功能实时动态监控系统进程与资源占用(CPU、内存、负载),默认按 CPU 使用率排序

bash 复制代码
top  # 直接执行进入监控界面


q:退出 top 界面
M:按内存占用率排序
P:恢复按 CPU 使用率排序

(9)ifconfig:

**功能:**查看网卡信息

bash 复制代码
ifconfig  # 查看所有激活网卡的信息

ip addr    #推荐使用

(10)ping :

功能 :测试本机与目标主机的网络连通性和网络质量,基于 ICMP 协议

bash 复制代码
ping www.baidu.com  # 测试与百度服务器连通性
ping 192.168.1.1   # 测试局域网内设备连通性

ping -c 4 www.baidu.com  # -c:指定发送数据包数量,发送4次后自动停止(避免无限ping)

2.2.10 dpkg工具集

dpkg底层包管理工具 ,仅能管理本地已下载的 .deb 格式安装包,无法自动解决软件依赖问题,依赖缺失会导致安装失败。

bash 复制代码
#安装软件
sudo dpkg -i filename.deb   # -i=install

#查看软件是否安装成功(已安装的软件)
dpkg -l | grep 软件名

#彻底卸载软件(删除配置)
sudo dpkg -p 软件名     # -P=purge,彻底删除程序 + 配置文件

#仅卸载软件(保留配置)
dpkg -r 软件名        #-r=remove,删除程序,保留配置文件

注意:

执行dpkg -i安装失败(提示依赖缺失)时,可通过 sudo apt-get install -f 修复依赖。

2.2.11 apt-get工具集

apt-get高级包管理工具 ,基于dpkg封装,自动从软件源下载包、解析并安装所有依赖 ,是日常安装软件的首选;新版系统推荐使用简化版命令 apt,功能一致且更易用。

可以自己根据配置的源下载对应的软件

根据软件依赖关系安装软件所需要的所有依赖
1、网络检测,先查看是否可以上网:

ping 8.8.8.8 # 检测外网连通性,正确

ping -c 4 8.8.8.8 # 推荐用法:发送4个包后自动停止,避免无限ping

若无法上网,则:

(1)让虚拟机使用NAT模式:

点击"虚拟机"

点击"设置"

点击"虚拟网络适配器"

选择"NAT模式"

点击"确认"

(2)修改Ubuntu配置文件

打开配置文件:

sudo vim /etc/network/interfaces

修改配置文件为如下格式:

auto lo

iface lo inet loopback

auto ens33

iface ens33 inet dhcp

保存退出

:wq

(3)重启Ubuntu

sudo reboot / sudo shutdown -r now

2、配置apt-get工具集的源

(1)点击"Ubuntu Software"

(2)右键选择"Software & Updates"

(3)「Download from」选择「Other」,筛选国内镜像源,源选择 aliyun

(4)点击"close"

(5)输入命令

sudo apt-get autoclean # 清理旧版本安装包缓存

sudo apt-get update # 刷新软件源缓存(必须执行,同步最新软件列表)

sudo apt-get install -f # 修复系统中缺失的依赖包

3、软件安装

#安装软件

sudo apt-get install 软件名 #自动处理依赖

#彻底卸载软件

sudo apt-get remove 软件名 --purge

sudo apt-get purge 软件名

#卸载软件(保留配置)

sudo apt-get remove 软件名

3、shell编程

3.1 解释型语言与编译型语言

**解释型语言:**边翻译边执行,不生成独立可执行文件

核心特点: 开发效率高、执行效率较低、适合做复杂数据运算、适合对系统自动化管理

**代表语言:**Shell、Python

**编译型语言:**源码先通过编译器编译为机器码文件,再直接执行(先编译再执行)

**核心特点:**开发效率低、执行效率高、运行速度快、适合做大规模数据运算,有丰富的数据类型和底层操作能力

**代表语言:**c/c++、c#

3.2 shell脚本开发流程

bash 复制代码
#脚本首行规范:必须添加解释器声明
#!/bin/bash
# 这是注释,# 开头的行不会被执行

# 1. 编辑脚本(推荐指定bash解释器)
vim test.sh

# 2. 添加执行权限
chmod +x test.sh

# 3. 相对路径执行(运行)
./test.sh

shell脚本本质:

Shell 脚本是一系列 Shell 命令、语法结构、变量的有序集合,系统逐行解析执行,实现自动化操作。

3.3 shell脚本中的引号

bash 复制代码
echo "当前路径:$(pwd)"
引号类型 语法规则 变量解析 命令执行 示例
双引号 " " 弱引用 解析变量,替换为变量值 支持$()执行命令 echo "当前目录:$PWD"
单引号 ' ' 强引用 不解析变量,原样输出 不执行任何命令 echo '输出纯文本 $PWD'
反引号 命令替换 执行引号内命令,输出结果替换自身 执行系统命令 ``echo 当前时间:```date`

注意:

反引号可读性差,现代 Shell 推荐用 $() 替代反引号,功能一致且支持嵌套

3.4 shell中的变量

3.4.1 预定义环境变量

系统内置变量,存储系统配置信息,可直接调用(shell脚本中用来存放系统相关信息的变量)

  • PWD:当前工作目录的绝对路径
  • HOME:当前用户的家目录
  • PATH:系统查找可执行文件的路径集合(系统软件默认的路径)
  • SHELL:当前使用的 Shell 解释器类型

3.4.2 位置参数变量

用于接收脚本执行时传入的外部参数,是脚本交互核心:

变量 含义
$0 当前脚本的文件名 / 路径
$1 第一个传入参数
$2 第二个传入参数
$# 传入参数的总个数
$? 上一条命令的退出状态码0= 执行成功,非0= 执行失败
$$ 当前脚本运行的进程 ID号(PID)

示例./test.sh a b c,则 $1=a$2=b$3=c$#=3

3.4.3 自定义变量

定义规则

  • 格式:变量名=值等号两侧绝对不能有空格(Shell 语法强制要求)
  • 变量名规范:由字母、数字、下划线组成,不能以数字开头
  • 调用变量:$变量名${变量名}(推荐后者,避免变量名歧义)

示例:

bash 复制代码
# 定义变量
i=0
str="hello world"
# 调用变量
echo $i
echo ${str}_shell  # 拼接字符串,{}区分变量边界

3.5 流程控制语句

3.5.1 分支语句:if

基本格式:

bash 复制代码
if [ 表达式 ]; then  # 推荐简写格式,[] 两侧必须有空格
    语句块
elif [ 表达式 ]; then
    语句块
else
    语句块
fi


if [ 条件 ]
then  # 如果then换行,可以省略分号
    语句
fi
test[]

[ 表达式 ] 等价于 test 表达式,用于条件检测,常用场景:

  • 数值比较:-eq(等于)-ne(不等于)-gt(大于)-lt(小于)
  • 文件检测:-f 判断是否为普通文件-d 判断是否为目录
  • 字符串比较:= 判断相等

示例

bash 复制代码
num=10
if [ $num -gt 5 ]; then
    echo "数字大于5"
fi


# Bash支持两种语法,推荐第一种
if [[ $str == "test" ]]; then  # [[ ]] 是Bash关键字,更强大
    echo "匹配"
fi

# 使用(( ))进行算术比较
if (( a > b )); then
    echo "a大于b"
fi
特性 [[ ]] (( ))
类型 条件表达式 算术表达式
用途 字符串、文件测试 数值计算和比较
返回值 逻辑真/假(0/1) 算术结果(数值)
是否需要$ 需要变量前的$ 不需要变量前的$
示例 [[ $str == "test" ]] (( a > b ))

3.5.2 多分支:case

bash 复制代码
case 变量值 in
    9)
        语句块
        ;;  # 每个分支必须以双分号结尾
    8)
        语句块
        ;;
    *)  # 通配符,匹配所有未命中的情况(默认分支)
        语句块
        ;;
esac  # case的结束标记,是case的反写

支持通配符匹配 ,可匹配多个值:9|8|7) 语句块 ;;

4、循环语句

4. 1 for循环

格式 1:遍历列表

bash 复制代码
# 遍历字符串/文件列表
for var in 1 2 3 4 5
do
    echo "数值:$var"
done
格式 2:类 C 语言风格
bash 复制代码
for ((i=0; i<5; i++))
do
    echo $i
done

4.2 while循环

条件为时循环执行,适用于未知循环次数场景:

bash 复制代码
i=1
while [ $i -le 5 ]
do
    echo $i
    i=$((i+1))  # 数值自增运算
done

4.3 until循环

条件为时循环执行,与 while 逻辑相反:

bash 复制代码
i=1
until [ $i -gt 5 ]
do
    echo $i
    i=$((i+1))
done

4.4 循环控制关键字

  • break:跳出整个循环
  • continue:跳过当前次循环,执行下一次

5、数组

Shell 仅支持一维数组,不支持多维数组,核心用法:

bash 复制代码
# 方式1:直接赋值
arr=("apple" "banana" "orange")
# 方式2:指定下标赋值
arr[0]="red"
arr[1]="blue"

echo ${arr[0]}        # 获取单个元素
echo ${arr[*]}        # 获取所有元素
echo ${#arr[*]}       # 获取数组长度

6、函数

Shell 函数用于封装复用代码,无返回值类型限制,通过状态码 /echo 传递结果。

6.1 函数定义

bash 复制代码
# 标准格式
function 函数名() {
    语句块
    # return 数字:设置函数退出状态码(0-255)
}

# 简化写法(省略function关键字,更常用)
函数名() {
    echo "执行函数:$1"  # 函数内 $1 接收第一个参数
}

6.2 函数调用与参数

bash 复制代码
# 调用函数,直接写函数名,后接参数
print_info "hello" "shell"

# 函数内获取参数:$1 $2 $# 规则与脚本位置参数一致

6.3 获取函数结果

bash 复制代码
# 方式1:通过echo输出结果,外部用$()接收
add() {
    echo $(( $1 + $2 ))
}
res=$(add 1 2)
echo "计算结果:$res"

7、expr:表达式计算器

基本功能:

expr 主要用于整数运算、字符串操作和逻辑比较

bash 复制代码
# 整数运算(注意:运算符两侧必须有空格)
expr 10 + 5      # 输出: 15
expr 20 - 3      # 输出: 17
expr 6 \* 3      # 输出: 18(*需要转义)
expr 15 / 4      # 输出: 3(整数除法)
expr 15 % 4      # 输出: 3(取模)

# 字符串长度
expr length "hello"   # 输出: 5

# 子串查找
expr index "hello" "l"  # 输出: 3(第一个'l'的位置)

# 子串提取
expr substr "hello" 2 3  # 输出: ell(从第2位开始取3个字符)
bash 复制代码
# expr的现代替代
# 算术运算 → $(( ))
echo $((10 + 5))      # 15
echo $((20 * 3))      # 60(不需要转义)

# 字符串长度 → ${#var}
str="hello"
echo ${#str}          # 5

# 子串提取 → ${str:start:length}
echo ${str:1:3}       # ell

8、seq:序列生成器

基本用法:生成数字序列

bash 复制代码
# 生成1到5
seq 5
# 输出:
# 1
# 2
# 3
# 4
# 5

# 指定范围
seq 3 7
# 输出:
# 3
# 4
# 5
# 6
# 7

# 指定步长
seq 1 2 10
# 输出:
# 1
# 3
# 5
# 7
# 9

# 反向序列
seq 10 -2 1
# 输出:
# 10
# 8
# 6
# 4
# 2

实际应用:

bash 复制代码
# 批量创建目录
for i in $(seq 1 10); do
    mkdir "day$i"
done

现代替代方案:

bash 复制代码
# Bash的brace expansion(简单序列)
echo {1..5}           # 1 2 3 4 5
echo {1..10..2}       # 1 3 5 7 9
echo {10..1..-2}      # 10 8 6 4 2

# for循环替代
for i in {1..5}; do
    echo $i
done

# 使用C语言风格的for循环
for ((i=1; i<=5; i++)); do
    echo $i
done
相关推荐
-Try hard-3 小时前
Linuv软件编程 | Shell命令
linux·运维·服务器
释怀不想释怀3 小时前
Linux快捷键,软件安装启动
linux·运维·服务器
zhengfei6113 小时前
自动化快速评估工具
运维·自动化
Hello World . .3 小时前
Linux:软件编程
linux·运维·服务器·vim
人间打气筒(Ada)3 小时前
k8s:CNI网络插件flannel与calico
linux·云原生·容器·kubernetes·云计算·k8s
老师用之于民4 小时前
【DAY21】Linux软件编程基础&Shell 命令、脚本及系统管理实操
linux·运维·chrome·经验分享·笔记·ubuntu
路由侠内网穿透.4 小时前
本地部署代码托管解决方案 Gitea 并实现外部访问( Windows 版本)
运维·服务器·网络协议·gitea
serve the people4 小时前
python环境搭建 (十三) tenacity重试库
服务器·python·php
jake don4 小时前
GPU服务器搭建大模型指南
服务器·人工智能