嵌入式学习

共享文件夹的路径 forlinx@ubuntu:/mnt/hgfs/share$

查找文件路径sudo find / -type d -name “OK113i-linux-sdk” 2>/dev/null

源码路径 /home/forlinx/work/OK113i-linux-sdk

cp /home/forlinx/work/OK113i-linux-sdk/out/t113_i_linux_ok113i_uart0.img /mnt/hgfs/share/

scp /home/forlinx/work/OK113i-linux-sdk/out/t113_i/ok113i/longan/boot.img

root@192.168.0.232:/home/

ssh-keygen -f “/home/forlinx/.ssh/known_hosts” -R “192.168.0.232” ssh清除密码

mkdir -p /run/media/mmcblk0p1 

mount /dev/mmcblk0p1 /run/media/mmcblk0p1

嵌入式学习

reg add HKLMSYSTEMCurrentControlSetServicesTcpipParameters /v IPEnableRouter /t REG_DWORD /d 1 /f 主机连了 Wi-Fi,同时通过网线连接开发板,虚拟机需要通过主机访问开发板。

查看当前启动服务

ls /etc/init.d/ ls /etc/rcS.d/

Linux 常用命令说明

touch

功能:创建大小为0的一个空文件参数:touch 文件名

mv

英文全拼:move功能:可以将一个目录移到另一个目录或者对文件进行改名参数:mi 源文件/目录 目的文件/目录 移动文件不要加/

echo

功能:将内容回显到输出设备,echo命令加上重定向可以创建带内容的文件。参数:echo 内容 或者“内容”>文件

cp 命令

英文全拼‌:copy

功能‌:实现文件的复制操作

参数

‌:

-r:递归复制目录下的文件和目录

-a:复制目录时,保留链接、文件属性并递归复制目录下的内容

-d:复制时保留链接

-p:将访问权限以及修改时间也复制到新文件中

-i:若存在目标文件需要用户确认操作

-f:强制复制,如果目标文件已存在则删除不提示

-v:显示文件复制过程

file 命令

功能‌:读取文件头并识别文件

参数

‌:

-b:列出辨识结果时,不显示文件名称

-f:指定名称文件

-v:显示版本信息

cat 命令

英文全拼‌:concatenate

功能‌:用于连接文件或将文件打印到标准输出设备上

参数‌:直接跟文件名即可

more 命令

功能‌:用于分页查看文件内容,适用于中等大小的文件。

常用操作‌:

空格(或 Ctrl+f)‌:向下翻一页。

b(或 Ctrl+b)‌:往回翻一页,但仅对文件有效,对管道输出无效。

Enter‌:向下滚动一行。

‌‌:显示文件名以及当前显示的行数。

=‌:输出当前的行号。

q‌:退出 more,不再显示文件内容。

参数‌:more [选项] 文件名

less 命令

功能‌:less 命令是 more 命令的升级版,功能更强大,支持前后翻页,适用于大文件或日志文件。

常用操作‌:

空格‌:向下翻一页(或 PageDown)。

PageUp‌:向上翻一页。

Enter(或 ↓)‌:向下滚动一行。

‌:向上滚动一行。

/字符串‌:向下搜索指定的字符串。

?字符串‌:向上搜索指定的字符串。

n‌:重复前一个搜索,方向向下。

N‌:重复前一个搜索,方向向上。

q‌:退出 less,不再显示文件内容。

额外功能‌:

less‌ 支持更多快捷键,如 ‌g‌ 跳转到文件开头,‌G‌ 跳转到文件末尾。

可以使用 ‌-N‌ 参数显示行号,使用 ‌-S‌ 参数禁用折行。

whereis 命令

用于定位文件位置,参数格式:whereis [选项] 文件名。常用选项:

-b‌:只查找二进制文件。

-m‌:只查找帮助文件。

-s‌:只查找源代码文件。

-B

-M

find 命令

在指定目录下查找文件,参数格式:find 目录 [选项] 查找条件。常用选项:

-name‌:文件名称符合。

-iname‌:文件名称符合,‌忽略大小写‌。

grep 命令

用于查找文件里符合条件的字符串,参数格式:grep [选项]。常用选项:

-r‌:递归查找符合条件的文件。

-n‌:显示匹配行的行号。

-i‌:忽略大小写进行匹配。

Linux中常见的压缩文件扩展名及说明

.gz‌:‌gzip压缩生成的文件‌。gzip是由GNU计划开发出的压缩命令,应用广泛。

.bz2‌:‌bzip2压缩生成的文件‌。bzip2提供了比gzip更好的压缩比。

.tar‌:‌tar打包的数据,没有进行压缩‌。tar命令可以将多个文件打包成一个文件,但本身不具备压缩功能。

.tar.gz‌:‌tar打包的数据,经过了gzip压缩‌。结合了tar的打包功能和gzip的压缩功能。

.tar.bz2‌:‌tar打包的数据,经过了bzip2压缩‌。结合了tar的打包功能和bzip2的压缩功能。

gzip 命令

功能

压缩‌:将文件压缩为gz格式。

解压缩‌:对gz格式的文件进行解压缩。

限制‌:仅能针对单个文件进行压缩和解压缩。

参数

gzip [选项] 文件名

选项 说明
-c 在标准输出上写入,保持源文件不变
-k 保持源文件不变
-d 解压缩
-r 对目录进行递归操作(但仅压缩目录下的文件)

bzip2 命令

功能

压缩‌:将文件压缩为bz2格式。

解压缩‌:对bz2格式的文件进行解压缩。

限制‌:仅能针对单个文件进行压缩和解压缩。

参数

bzip2 [选项] 文件名

选项 说明
-c 输出到标准输出
-k 保持源文件不变
-d 解压缩

zcat 命令

功能

解压并输出‌:将gz格式的文件解压缩到标准输出。

参数

zcat gz格式文件

bzcat 命令

功能

解压并输出‌:将bz2格式的文件解压缩到标准输出。

参数

bzcat bz2格式文件

tar 命令

英文全拼

tape archive

功能

文件打包工具‌:用于将多个文件和目录打包成一个归档文件(称为 “tarball”),通常带有 .tar 扩展名。tar 本身不压缩文件,但可以与压缩工具结合使用,创建压缩的归档文件(如 .tar.gz.tar.bz2)。

常用参数

选项 说明
-c 创建一个新的归档文件
-x 解压归档文件
-t 列出归档文件的内容
-f 指定归档文件的名称,与其他选项同时使用时必须放在最后
-v 显示详细处理信息
-C 转到指定目录进行操作,一般用于解压文档
-j 调用 bzip2 程序进行压缩或解压
-z 调用 gzip 程序进行压缩或解压
--exclude=PATH 排除指定目录或文件,用于打包时排除不需要的文件

其他重要选项

-r:向现有归档文件中追加文件。

-u:仅追加比归档文件中已有文件更新的文件。

--transform=<expression>:重命名归档中的文件。

--strip-components=<number>:解压时剥离指定数量的路径组件。

示例

创建归档文件‌:tar -cvf archive.tar file1 file2 directory

解压归档文件‌:tar -xvf archive.tar

压缩归档文件‌:tar -zcvf archive.tar.gz directory(使用 gzip 压缩)

用户组配置文件说明

/etc/passwd 文件内容

用户名‌:elf

UID‌:1000

密码标志‌:x(表示密码被加密并存储在 /etc/shadow 文件中)

GID‌:1000

用户说明‌:elf,,(通常包含用户的全名或其他描述信息,此处为空)

家目录‌:/home/elf

shell‌:/bin/bash

/etc/shadow 文件内容

用户名‌:elf

加密密码‌:$6$XqMqLXNw$89WhQcYC15HgjyU(经过加密的密码)

最后一次密码修改时间‌:19487(通常是一个时间戳)

密码最小修改间隔‌:0(表示密码可以随时更改)

密码最大有效期‌:99999(表示密码在很长时间内有效)

密码到期前警告天数‌:7(在密码到期前7天开始警告)

密码到期后宽限天数‌:无(:: 表示没有设置宽限天数)

账户失效时间‌:无(:: 表示账户不会失效)

注意事项‌:/etc/shadow 文件存储了用户的加密密码和其他密码相关信息,是系统中非常敏感的文件,通常只有 root 用户才有权限读取和修改。

/etc/group 文件

格式‌:组名:密码:GID:附加用户

示例:

sambashare:x:126:elf

组名‌:sambashare

密码‌:x(表示加密后的密码)

GID‌:126

附加用户‌:elf

/etc/gshadow 文件

格式‌:组名:密码:组管理员:附加用户

示例:

elf:!::

组名‌:elf

密码‌:!(表示密码被禁用或未设置)

组管理员‌:无

附加用户‌:无

注意‌:/etc/group 存储用户组的基本信息,而 /etc/gshadow 存储用户组的密码及管理员信息,用于增强安全性。

useradd

功能‌:用于创建新用户

基本语法‌:useradd [选项] 用户名

常用选项‌:

-m‌:若主目录不存在则自动创建用户家目录。

-d 目录‌:指定用户家目录的具体路径。

-u UID‌:手动为用户设置唯一的用户ID(UID)。

-g 组名‌:指定用户的主要组,且该组必须已存在。

-G 组名‌:指定用户的附加组,附加组必须已存在,可指定多个,用空格隔开。

-s‌:指定用户的登录Shell,如/bin/bash

passwd

功能‌:设置或修改用户密码

基本语法‌:passwd [选项] 用户名

常用选项‌:

无选项:普通用户修改自己的密码,root用户可修改任意用户的密码。

-S‌:查询用户的密码状态。

-l‌:锁定用户账户。

-u‌:解锁用户账户。

–stdin‌:允许从标准输入读取密码,用于脚本自动化。

adduser

功能‌:在某些系统中,adduseruseradd的友好前端,用于添加用户

基本语法‌:adduser [选项] 用户名

常用选项‌(注意,这些选项可能因系统不同而有所差异):

–group 组名‌:在创建用户时同时创建用户组(某些系统中可能不适用)。

–home 目录‌:指定用户家目录。

–uid UID‌:指定用户ID。

–gid GID‌:指定用户的主要组ID或附加组ID(具体行为可能因系统而异)。

注意‌:adduser命令在交互性更强的系统中(如Debian系)会提示设置密码等额外信息,而useradd则更侧重于命令行操作。

符号 类型
普通文件
d 目录文件
l 软连接文件
b 块设备文件
c 字符设备文件
p 管道文件
s socket文件

Linux 文件权限详解

一、权限分类

Linux一般将文件的所属身份分为三类:

owner(所有者)

group(所属组)

others(其他用户)

二、权限类型

文件或目录具有的权限主要包括:

只读(read, r)

可写(write, w)

可执行(execute, x)

三、非目录文件权限

对于非目录文件,权限的具体含义如下:

r‌: 允许用户读取文件的实际内容。

w‌: 允许用户编辑、新增或修改文件内容。

x‌: 允许用户执行该文件(如果它是一个可执行程序)。

四、目录文件权限

对于目录文件,权限的具体含义有所不同:

r‌: 允许用户读取目录结构列表,即查看目录下的文件和子目录。

w‌: 允许用户修改目录结构列表,包括新建、删除、转移或重命名目录下的文件及子目录。

x‌: 允许用户进入该目录,使其成为当前工作目录。

五、权限查看与更改

查看权限‌:使用ls -l命令可以查看文件和目录的详细权限信息。

更改权限‌:使用chmod命令可以更改文件或目录的权限。权限可以通过符号表示法(如u+x给文件所有者添加执行权限)或数字表示法来指定。数字表示法基于权限的位运算特性,将读、写、执行分别赋予4、2、1的数值,从而组合出不同的权限设置。

通过以上内容,我们可以清晰地了解Linux系统中文件权限的管理机制,以及如何查看和更改这些权限。

chmod 命令详解

英文全拼

change mode

功能

设置用户对于文件的权限

参数格式

chmod [参数] 目录或文件

权限类型与字符表示

类型 Owner Group Others
权限 执行
字符 r w x

权限类型与数字表示

读(r):‌4

写(w):‌2

执行(x):‌1

组合示例:

7(rwx):4+2+1

5(r-x):4+1

用户类型符号

符号 含义
u 表示文件的所有者
g 表示文件的所属组
o 表示其他用户
a 表示所有用户(all)

操作符号

符号 含义
+ 增加某种权限
减少某种权限
= 赋予给定权限并取消其他所有权限

示例

chmod u+x file.txt:为文件 file.txt 的所有者增加执行权限。

chmod 755 directory/:设置目录 directory/ 的权限为所有者(rwx),所属组(r-x),其他用户(r-x)。

使用 chmod 命令时,可以灵活组合用户类型符号、操作符号以及权限字符或数字,以实现精细的权限管理。

chgrp 与 chown 命令详解

chgrp 命令

英文全拼‌:change group

功能‌:用于设置文件或目录的所属用户组。

参数‌:chgrp [选项] 组名 文件或目录

常用选项‌:

-R‌:递归修改,即修改指定目录及其下所有文件和子目录的所属组。

示例‌:

chgrp -R mengxin /usr/meng/

此命令将递归地更改 /usr/meng/ 目录下所有文件和子目录的所属组为 mengxin

chown 命令

英文全拼‌:change owner

功能‌:用于设置文件或目录的所有者和所属组。只有超级用户或文件的所有者才能使用该命令。

参数‌:chown [选项] [用户]:[组] 文件或目录

用户和组之间可以用冒号 : 分隔,也可以只指定用户(此时组不变)。

常用选项‌:

-R‌:递归修改,即修改指定目录及其下所有文件和子目录的所有者和组。

示例‌:

更改所有者:

shCopy Code
​
​
​
chown -R liu /usr/meng/

此命令将递归地更改 /usr/meng/ 目录下所有文件和子目录的所有者为 liu

同时更改所有者和组:

shCopy Code
​
​
​
chown -R liu:mengxin /usr/meng/

此命令将递归地更改 /usr/meng/ 目录下所有文件和子目录的所有者为 liu,所属组为 mengxin

注意事项‌:

在使用 chown 命令时,确保指定的用户和组在系统中存在(分别检查 /etc/passwd/etc/group 文件)。

使用冒号 : 连接所有者和组时,避免用户名或组名中包含小数点 .,以免造成系统误判。

挂载与卸载命令详解(md格式)

mount 命令

功能‌:挂载文件系统到指定目录。

基本语法‌:mount [参数] <设备名> <挂载点>

常用参数‌:

-t:指定文件系统类型,如 ext4ntfsvfat 等。

-o:指定挂载选项,如 rw(读写)、ro(只读)、user(允许普通用户挂载)等。

-l:显示当前系统中所有已挂载的文件系统列表。

-v:在挂载时显示详细信息。

-V:显示 mount 命令的版本信息。

常见挂载选项‌:

rw:以读写模式挂载文件系统。

ro:以只读模式挂载文件系统。

user:允许普通用户挂载文件系统。

noexec:禁止在文件系统中执行可执行文件。

umount 命令

功能‌:卸载已挂载的文件系统。

基本语法‌:umount [参数] <设备名/挂载点>

常用参数‌:

-a:卸载 /etc/fstab 中定义的所有文件系统。

-r:懒惰卸载,标记文件系统为卸载状态,随后在文件系统不再使用时真正卸载。

-f:强制卸载,即使设备正在被使用。

-n:不更新 /etc/mnttab 文件。

-v:显示卸载过程的详细信息。

-V:显示 umount 命令的版本信息。

注意事项‌:

在卸载文件系统之前,确保没有进程正在使用该文件系统,否则卸载可能失败。

使用 lsoffuser 命令可以查看哪些进程在使用某个挂载点,便于及时处理。

文件系统特性详解

inode

定义‌:inode(索引节点)是文件系统中用于记录文件属性的数据结构。

功能‌:每个文件占用一个inode,描述文件的属性,如‌权限‌、‌所有者‌、‌大小‌、‌创建/访问/修改时间‌以及指向数据块(block)的‌指针‌等。

特性‌:通过inode号唯一标识文件,即使文件名改变,inode号仍保持不变。

block

定义‌:block(数据块)是文件系统中用于存储文件内容的固定大小的数据单元。

功能‌:存储文件的实际数据。若文件较大,可占用多个block。

特性‌:

普通文件的block存储文件数据。

目录文件的block存储目录项信息,包括文件的inode号、文件名、文件类型等。

super block

定义‌:super block(超级块)是文件系统的核心元数据结构。

功能‌:包含文件系统的关键信息,如block和inode的‌总量‌、‌使用量‌、‌剩余量‌以及‌文件系统状态‌等。

特性‌:是文件系统的“目录索引”,确保文件系统的一致性和完整性,在文件系统挂载和访问时起到关键作用。

硬连接详解

硬连接(Hard Link)‌是通过文件系统的inode连接来产生新文件名,而不是产生新文件。以下是硬连接的详细解释:

基本概念‌:

硬连接是指多个文件名指向同一个inode(索引节点)。

在Linux文件系统中,每个文件都会被分配一个唯一的inode编号。

结构说明‌:

目录文件inode‌:存储了文件或目录的元数据,包括文件名、权限、所有者等,并指向对应的inode。

例如,/home/elf/work1/file1/home/elf/work2/file2 可能指向同一个inode。

文件inode‌:存储了文件的实际数据块信息。

目录block‌:指向inode的指针,用于在目录中查找文件。

文件block‌:存储文件的实际内容。

硬连接特点‌:

多个入口‌:一个文件可以有多个硬连接,即多个文件名指向同一个inode。

数据共享‌:所有硬连接共享同一份数据,修改任何一个硬连接的内容,其他硬连接都会看到变化。

防止误删‌:即使删除了其中一个硬连接,只要还有其他硬连接存在,文件数据就不会被删除。只有当最后一个硬连接被删除时,文件数据才会被释放。

创建与删除‌:

创建硬连接:使用ln命令,如ln 源文件 硬链接文件

删除硬连接:使用rm命令,如rm 硬链接文件。但注意,这只会删除硬连接,不会删除文件数据。

注意事项‌:

目录不能创建硬连接,但可以创建软连接(符号链接)。

硬链接不能跨越文件系统。

符号连接/软连接详解‌:

定义‌:符号连接(软连接)是创建一个独立的文件,该文件的数据部分仅包含要连接的文件的路径名。

inode关系‌:

连接文件拥有自己的inode(如No.3)。

它不直接指向文件内容,而是指向目标文件的路径。

block内容‌:

连接文件block‌:存储了目标文件的路径,如/home/elf/work1/file1

目录block‌:包含连接文件的目录信息。

目标文件block‌:存储实际文件内容。

连接文件命令——ln(转为md格式)

ln命令简介

英文全拼‌:link files

功能‌:ln命令用于为某一个文件在另外一个位置建立一个同步的链接,分为硬链接和软链接(符号链接)两种。

命令格式

ln [选项] 源文件 目标文件

选项说明

选项 说明
-s 创建软链接(符号链接)‌。软链接类似于Windows的快捷方式,可以跨文件系统,删除软链接不会影响原始文件。
-v 显示详细的处理过程‌。在执行链接操作时,会显示详细的操作信息。

硬链接与软链接的区别

硬链接‌:指向文件数据的指针,不是文件名。多个硬链接可以指向同一份文件数据,删除其中一个硬链接不会影响其他硬链接或原始文件。硬链接不能跨文件系统,且不能为目录创建硬链接。

软链接‌:包含了指向另一个文件的路径的独立文件。软链接可以跨文件系统,删除软链接不会影响原始文件。但如果软链接指向的文件被删除,软链接会变成一个无效链接。

使用示例

创建硬链接‌:ln file.txt hardlink.txt(在当前目录下为file.txt创建一个名为hardlink.txt的硬链接)

创建软链接‌:ln -s /home/user/documents /home/user/links/docs_link(在/home/user/links目录下创建一个指向/home/user/documents目录的软链接docs_link

网络相关命令——ifconfig

ifconfig命令功能

显示或配置Linux系统中的网络接口参数‌。

ifconfig命令的基本语法

ifconfig [网络接口] [选项] 地址/参数

ifconfig命令的常用选项及说明

ifconfig -a‌:‌显示所有网络接口的信息,包括未激活的接口‌。

ifconfig ens33 172.16.0.151‌:‌为ens33网络接口设置IP地址为172.16.0.151‌。

ifconfig ens33 broadcast 172.16.0.255‌:‌设置ens33网络接口的广播地址为172.16.0.255‌。

ifconfig ens33 netmask 255.255.255.0‌:‌设置ens33网络接口的子网掩码为255.255.255.0‌。

ifconfig ens33 hw ether 22:22:22:22:22:22‌:‌为ens33网络接口设置MAC地址为22:22:22:22:22:22(需先关闭接口再设置,设置后重新启用)‌。

ifconfig ens33 up‌:‌激活ens33网络接口‌。

ifconfig ens33 down‌:‌关闭ens33网络接口‌。

网络相关命令 – ping

功能

ping‌ 命令用于检查网络的连接情况,通过发送 ICMP(Internet Control Message Protocol)回显请求和响应消息来判断目标主机是否可达,以及获取连接的丢包率和平均往返时间等状态信息。

参数

ping [选项] IP地址/域名

选项 说明
-c 设置完成要求回应的次数
-i 指定收发信息的间隔时间
-n 只输出数值,不显示主机名

详细说明

工作原理‌:ping 命令通过发送 ICMP Echo 请求数据包到目标主机,并等待 ICMP Echo 回复数据包来判断网络连接状态。

应用场景‌:常用于测试本地主机与远程主机之间的网络连接是否通畅,以及判断网络配置是否正确。

注意事项‌:ping 成功并不一定代表 TCP/IP 配置完全正确,还需考虑其他网络配置因素。若 ping 成功但网络仍无法使用,可能是网络系统的软件配置问题。

网络相关命令

route 命令详解

功能

添加、删除或查看网关参数,是网络配置中的重要工具。

参数说明

基础参数:route,用于启动该命令。

操作示例

添加默认网关‌:

bashCopy Code
​
​
​
sudo route add default gw 192.168.0.1

此命令将默认网关设置为 192.168.0.1。

删除默认网关‌:

bashCopy Code
​
​
​
sudo route del default gw 192.168.0.1

此命令将删除当前的默认网关设置。

nameserver 配置说明

功能概述

主要功能‌:使用域名访问 DNS 服务,需预先设置 DNS 参数。

参数设置

关键参数‌:nameserver xx.xx.xx.xx(请将 xx.xx.xx.xx 替换为实际的 DNS 服务器 IP 地址)。

配置位置

存放路径‌:该设置需存放在系统的 /etc/resolv.conf 文件中,以确保网络域名解析正常进行。

进程相关命令ps

功能‌:显示当前操作系统中由该用户运行的进程列表。

常见参数‌:

-a:显示所有与终端相关的进程。

-u:查看进程所有者及其详细信息。

-x:显示没有控制终端的进程。

-e:显示所有进程。

-l:‌显示详细信息‌,例如优先级、父进程等。

top 命令说明

功能

动态显示当前系统中由该用户运行的进程列表‌。top 命令是 Linux 系统管理员和开发人员常用的工具,用于实时监控系统的运行状态。

参数

‌:运行 top 命令时不带任何参数,将显示默认的进程和系统信息界面。

使用说明

界面组成

系统信息‌:显示系统的一般信息,包括运行时间、活跃用户数量、负载平均值和运行中的进程数量。

任务摘要‌:显示总活动任务的摘要,包括进程数量及其状态。

系统进程列表‌:详细列出每个进程的 PID、用户、CPU 使用率、内存使用率和命令信息等。

常用选项

-d:设置屏幕更新之间的时间间隔。

-p:监控特定的进程 ID。

-n:定义 top 退出前的迭代次数。

-b:批处理模式,将输出捕获到文件中。

-u:显示特定用户的进程。

-s:安全模式,隐藏或掩蔽某些信息。

-i:忽略空闲和僵尸进程。

-o:根据特定字段(如 CPU 使用率)对进程进行排序。

-H:显示单独的线程。

-c:显示命令名称而不是命令行参数。

交互式命令

h:显示帮助信息。

k:使用 PID 杀死进程。

q:退出 top 界面。

z:切换颜色/单色模式。

r:调整进程的优先级。

u:通过特定用户过滤进程。

P:按 CPU 使用率排序进程。

M:按内存使用率排序进程。

T:按运行时间排序进程。

c:切换显示命令行。

1:切换显示单个 CPU 状态。

高级选项

在安全模式下运行,隐藏或掩蔽某些信息。

使用 V 键查看进程的树状结构。

使用 Z 键(具体可能因 top 版本而异)进行其他高级操作。

kill 命令说明

功能‌: 强制终止进程

使用参数‌:

kill -signal pid 其中,signal 是要发送的信号(如 9 代表强制终止),pid 是要终止的进程 ID。

示例‌: 如果你想要强制终止进程 ID 为 1234 的进程,可以使用以下命令:

kill -9 1234

clear 命令说明

功能‌:清除屏幕 ‌参数‌:无

sync 命令说明

功能‌:将文件系统的缓冲区数据立即写入磁盘中,确保文件系统的数据与磁盘数据保持同步,防止数据丢失或损坏。

详细解释‌:

数据同步机制‌:在Linux系统中,为了提高性能,数据写入磁盘并不是即时完成的,而是先缓存到内存中。sync命令的作用就是将内存中的这些数据强制写入磁盘。

使用场景‌:在关机、重启或卸载文件系统前,建议多次执行sync命令,以确保数据完整性。此外,在备份数据或管理高负载服务器上的文件系统时,sync也是不可或缺的工具。

基本语法‌:sync [选项] [文件...]。不带选项时,sync会同步所有文件系统的缓存;指定文件时,仅同步该文件的缓存数据和元数据。

安装与环境‌:sync命令是coreutils软件包的一部分,默认包含在几乎所有Linux发行版中。如未安装,可通过包管理器进行安装。

man 命令使用说明

功能

显示Linux系统命令、函数、配置文件、系统调用的帮助信息

语法格式

man [选项] 命令/函数

选项说明

选项 说明
无选项(直接跟命令) 显示该命令的详细帮助信息
-a 在所有手册页中搜索关键词
-k 模糊搜索相关手册(相当于搜索标题)
-f 快速查看该命令属于哪一类及其简要说明
-w 显示手册页文件的路径但不显示其内容
-P [pager] 指定用于显示手册页的分页程序
-s [num] 仅在指定的手册章节内搜索
数字(如1, 2, 3等) 指定章节查看,比如系统调用、库函数等

手册章节解释

1‌:用户命令(如ls, cp)

2‌:系统调用(如open, read)

3‌:库函数(如printf, malloc)

4‌:设备文件和驱动

5‌:配置文件格式(如/etc/passwd)

6‌:游戏和娱乐

7‌:杂项(如协议、文件格式描述)

8‌:系统管理命令(如mount, ifconfig)

9‌:内核例程,面向Linux内核开发者

快捷键

空格键‌:向下翻页

b‌:向上翻页

/关键字‌:搜索关键字

n‌:跳到下一个搜索结果

q‌:退出man页面

示例

查看ls的官方文档:man ls

查看系统调用open:man 2 open

模糊搜索包含copy的命令:man -k copy

快速查看ls命令类型:man -f ls

工作模式(转为md格式)

vim工作模式详解

三种核心工作模式

一般模式(Normal Mode)

功能‌:进行光标的移动、复制、粘贴、删除等基本操作。

进入方式‌:Vim启动后默认进入此模式,或在其他模式下按Escape(Esc)键返回。

编辑模式(Insert Mode)

功能‌:进行文本编辑,如输入、修改文本内容。

进入方式‌:在一般模式下按i键进入。

退出方式‌:按Esc键返回一般模式。

命令模式(Command Mode 或 Last Line Mode)

功能‌:执行保存文件、退出编辑器、查找、替换等高级操作。

进入方式‌:在一般模式下按:键进入。

常用命令

‌:

:w:保存文件。

:q:退出编辑器。

:wq:保存并退出。

/pattern:搜索指定模式。

:s/old/new/g:全局替换。

模式切换总结

一般模式到编辑模式‌:按i键。

编辑模式到一般模式‌:按Esc键。

一般模式到命令模式‌:按:键。

流程图说明

主要模式

光标插入指令‌:

使用ESC键退出至

一般模式

命令模式

编辑模式

ESC键功能‌:

从任意模式退出至

一般模式

直接进入‌命令模式‌或‌编辑模式

Vim 编辑器快捷键

移动光标

k 或 ↑‌:将光标‌上移一行

j 或 ↓‌:将光标‌下移一行

h 或 ←‌:将光标‌左移一个字符

l 或 →‌:将光标‌右移一个字符

屏幕翻页

Ctrl+f 或 Page Down‌:向‌下翻页

Ctrl+b 或 Page Up‌:向‌上翻页

其他常用命令

zz‌:将当前行置于屏幕‌中央

zt‌:将当前行置于屏幕‌顶部

zb‌:将当前行置于屏幕‌底部

Ctrl+e‌:向上移动‌一行

Ctrl+y‌:向下移动‌一行

Ctrl+u‌:向文件首翻‌半屏

Ctrl+d‌:向文件尾翻‌半屏

gg‌:光标移动到文件‌顶部

G‌:光标移动到文件‌尾部

Vim常用操作–一般模式

删除文本

dd‌:删除光标所在的整行内容。若在dd前增加数字,如2dd,则可以删除从光标所在行开始的两行。

d$‌:删除本行光标所在位置及以后的所有字符。

d^‌:删除本行光标之前的所有字符。

dw‌:删除从光标所在位置直到下一个单词开始的所有内容。

复制文本

yy‌:复制当前整行内容。

ynl‌:复制n个字符。

y^‌:复制当前行光标之前的内容。

y$‌:复制当前行光标之后的内容。

yw‌:复制光标所在的单词。

粘贴文本

p‌:粘贴已复制或剪切的内容。若在前面加上数字,如3p,则粘贴三次。

光标移动

h‌:光标左移。

j‌:光标下移。

k‌:光标上移。

l‌:光标右移。

w‌:光标移动到下一个单词的词头。

b‌:光标移动到上一个单词的词头。

gg‌:光标移动到文章开头。

G‌:光标移动到文章结尾。

行数+shift+g‌:光标移动到指定的某一行。

其他常用操作

u‌:撤销上一步操作。

Ctrl + r‌:恢复上一个被撤销的操作。

:w‌:保存文件。

:q‌:退出Vim。

:wq‌:保存并退出Vim。

:q!‌:不保存强制退出Vim。

:set nu‌:显示行号。

:set nonu‌:不显示行号。

/查找词+回车‌:进行查找,再按n向下遍历,N向上遍历。

指令 作用
/p1 查找 p1
:%s/p1/p2/g 在文件中将所有的 p1 替换为 p2
:%s/p1/p2/gc 在文件中将所有的 p1 替换为 p2,并在每次替换前进行确认

Shell脚本执行方法

执行要求

文件需具备可读和可执行权限

执行方式

1. 当前目录执行

./myshell.sh

2. 绝对路径下执行

/home/elf/myshell.sh

2. 绝对路径下执行

bashCopy Code
​
​
​
/home/elf/myshell.sh

3. 使用shell应用程序执行

bashCopy Code
​
​
​
bash myshell.sh

4. 使用source.执行

source是bash的内置命令

bashCopy Codesource myshell.sh
# 或
. myshell.sh  # 注意:.后边有空格

Shell脚本执行方式

一、在子shell中执行

父进程 shell‌:

当在子shell中执行脚本时,父shell的环境与子shell是隔离的。

变量‌:脚本中设置的变量在脚本执行完毕后不会保存,这些变量和环境设置在子shell中局部生效,不会影响当前(父)shell的环境。

子进程 shell‌:

子shell是由父shell派生出来的一个新的shell进程。

在子shell中执行的命令和脚本对父shell的状态无影响。

二、在当前shell进程中执行

父进程 shell‌:

如果直接在当前shell进程中执行脚本(例如使用.source命令),则脚本中设置的变量在脚本执行完毕后会保存下来。

变量‌:这些变量会保留在当前shell的环境中,方便与当前shell的环境进行交互,适用于修改环境变量、切换工作目录等情况。

执行方式‌:

使用.(点命令)或source命令来在当前shell中执行脚本,例如:. script.shsource script.sh

总结‌:

子shell执行‌:适用于需要隔离环境的场景,变量和环境设置在子shell中局部生效。

当前shell执行‌:适用于需要保留变量和修改当前shell环境的场景。

shell变量详解

什么是shell变量

变量‌是编程中用于存放数据的容器。在Shell脚本中,变量同样扮演着至关重要的角色,用于存储和引用数据。Shell变量无需事先声明类型,直接赋值即可使用,这符合Shell作为弱类型语言的特性。

shell变量的命名规则

组成‌:变量名由字母、数字和下划线组成。

开头‌:自定义变量必须以字母或下划线开头,不能是数字。

限制‌:不能使用Shell中的保留关键字,如$#?等。

shell变量的定义与赋值

赋值‌:使用=号进行赋值,如变量名=变量值

引号‌:变量值可以加上单引号或双引号,特别是当值中包含空格或特殊字符时。

空格‌:=两侧不能有空白符号,如空格或tab。

shell变量的类型与操作

类型‌:虽然Shell不强制要求变量类型,但根据用途可分为字符串变量、数值变量、环境变量等。

操作‌:包括变量替换、变量修改(如搜索和替换)、获取变量长度等。

shell变量的特殊用法

环境变量‌:由操作系统提供,用于配置程序环境,如PATHHOME等。

位置参数‌:执行脚本时传递给脚本的参数,可通过$1$2等访问。

局部变量与全局变量‌:局部变量仅在函数或当前shell会话中有效,全局变量在整个脚本中有效。

示例

# 定义变量
my_var="Hello, World!"
num1=5
num2=3
​
# 变量替换与输出
echo $my_var  # 输出: Hello, World!
sum=$((num1 + num2))
echo "The sum is $sum"  # 输出: The sum is 8
​
# 环境变量
echo "Your home directory is: $HOME"
echo "Current PATH is: $PATH"

shell脚本在vim写完然后用echo $变量名 查看

变量使用详解及Markdown格式示例

不同情况下的变量应用

将命令执行结果赋值给变量

方法一:反引号‌(不推荐,易混淆)

bashCopy Code
​
​
​
`date`  # 执行date命令,结果赋值给变量(示例,实际需赋值给具体变量)

示例‌:current_date=date`,然后echo $current_date`显示当前日期。

方法二:$()‌(推荐)

bashCopy Codefile_list=$(ls -l)  # 列出文件并赋值给变量
echo "$file_list"  # 打印文件列表

变量中引用变量或命令

单引号‌:直接当字符串输出,不解析变量。

bashCopy Codename="John"
echo 'Hello $name'  # 输出:Hello $name

双引号‌:解析变量。

bashCopy Codename="John"
greeting="Hello"
echo "$greeting $name"  # 输出:Hello John

删除变量

使用

unset

命令。

bashCopy Codename="John"
unset name
echo $name  # 无输出,变量已删除

只读变量

使用

readonly

命令,变量不可修改或删除。

bashCopy Codename="John"
readonly name
unset name  # 报错:bash: unset: readonly variable 'name' cannot be unset

Shell变量种类详解

本地变量

定义‌:仅在当前Shell会话中可见,对于其他的Shell和Shell执行的程序是不可见的。

特点‌:用户自定义,用于临时存储数据,脚本执行完毕后失效。

环境变量

定义‌:在操作系统中用来指定操作系统运行环境的一些参数,有些程序需要环境变量来保证其正常运行。

查看‌:可以使用env命令查看当前Shell环境中的所有环境变量。

配置文件‌:

用户级别‌:~/.profile~/.bashrc

系统级别‌:/etc/environment/etc/profile/etc/bash.bashrc

其他变量类型

位置变量‌:Shell脚本中通过位置引用的命令行参数,例如$1$2等代表第一个、第二个参数。

预定义特殊变量‌:如$0(脚本名)、$#(参数个数)、$*(所有参数)、$?(上一条命令的退出状态)等。

局部变量‌:在函数内使用local声明的变量,作用域限于函数内部。

总结‌:Shell变量种类繁多,每种变量都有其特定的用途和作用范围。理解并掌握这些变量的使用,对于编写高效、灵活的Shell脚本至关重要。

Shell特殊变量详解

在Shell脚本编程中,特殊变量扮演着至关重要的角色。以下是Shell中常见特殊变量的详细解释,以Markdown格式呈现:

位置参数变量

$0‌:‌Shell脚本本身的文件名‌。若脚本通过相对或绝对路径执行,则显示对应路径。

$1, $2, …, $n‌:传递给Shell脚本的第1, 第2, …, 第n个参数。例如,$1代表第一个参数。

参数相关变量

$#‌:传递给Shell脚本的参数个数。

$‌:所有参数列表,作为一个整体字符串输出。例如,"$*"会输出"$1 $2 ... $n"

$@‌:所有参数列表,但每个参数被视为独立的字符串。例如,"$@"会输出"$1" "$2" ... "$n"。在双引号中使用时,$*$@的区别尤为明显。

进程相关变量

$$‌:当前Shell进程的PID(Process ID,进程标识符)。

$!‌:最后一个在后台运行的进程的PID。

状态变量

$?‌:最后运行的命令的退出状态。0通常表示成功,非0值表示失败或错误。

以下是一些示例,展示了如何在脚本中使用这些特殊变量:

#!/bin/bash
echo "脚本名称: $0"
echo "第一个参数: $1"
echo "参数总数: $#"
echo "所有参数(作为一个字符串): $*"
echo "所有参数(每个参数独立): $@"
echo "当前进程ID: $$"
# 运行一个后台进程并获取其PID
sleep 10 &
echo "后台进程ID: $!"
# 运行一个命令并检查其退出状态
ls /nonexistent
echo "上条命令退出状态: $?"

数组操作的Markdown格式说明及使用指南

数组定义‌: 在Bash中,可以使用括号()来定义数组,例如Arr=(apple banana cherry)

数组使用‌:

访问单个元素‌:

使用${Arr[索引]}来访问数组中的单个元素,例如${Arr[0]}表示访问数组的第一个元素。

打包为字符串‌:

${Arr[*]}:将所有成员打包为一个由空格分隔的字符串。

${Arr[@]}:将所有成员分别打包,但在使用时,每个成员会作为独立的参数,常用于循环或命令中。

获取数组长度‌:

使用${#Arr[*]}${#Arr[@]}来获取数组的长度,即数组中元素的数量。

示例说明‌:

定义数组‌:Arr=(apple banana cherry)

打印数组长度‌:使用echo "数组长度: ${#Arr[*]}",输出数组长度: 3

打印数组所有成员

‌:

使用echo "数组成员: ${Arr[*]}",输出数组成员: apple banana cherry(成员间由空格分隔)。

使用echo "数组成员(每个单独一行): ${Arr[@]}",输出每个成员单独占一行。

定义数组

bashCopy Code
​
​
​
fruits=("苹果" "香蕉" "橙子" "葡萄")

访问数组元素

bashCopy Codeecho "第一个水果: ${fruits[0]}"  # 输出: 第一个水果: 苹果
echo "第三个水果: ${fruits[2]}"  # 输出: 第三个水果: 橙子

获取数组长度

bashCopy Code
​
​
​
echo "水果种类数量: ${#fruits[@]}"  # 输出: 水果种类数量: 4

遍历数组

bashCopy Codefor fruit in "${fruits[@]}"; do
    echo "水果: $fruit"
done

输出:

textCopy Code水果: 苹果
水果: 香蕉
水果: 橙子
水果: 葡萄

修改数组元素

bashCopy Codefruits[1]="芒果"  # 将第二个元素改为芒果
echo "${fruits[@]}"  # 输出: 苹果 芒果 橙子 葡萄

添加新元素

bashCopy Codefruits+=("西瓜")  # 在数组末尾添加新元素
echo "${fruits[@]}"  # 输出: 苹果 芒果 橙子 葡萄 西瓜

删除元素

bashCopy Codeunset fruits[2]  # 删除第三个元素
echo "${fruits[@]}"  # 输出: 苹果 芒果 葡萄 西瓜

Shell 运算符示例

运算符 说明
+、-、*、/、% 加、减、乘、除、取余
!、&&、|| 逻辑非(取反)、逻辑与(and)、逻辑或(or)
<、<=、>、>= 比较符号(小于、小于等于、大于、大于等于)
=、==、!= 比较符号(赋值、等于、不等于,注意:在 Shell 中=用于赋值,==用于比较)
<<、>> 向左移位、向右移位
&、|、~、^ 按位与、按位或、按位取反、按位异或

示例说明

算术运算

在 Shell 中,算术运算通常使用$(( ))expr命令。

bashCopy Code# 加法
echo $((2 + 3))  # 输出 5
​
# 减法
echo $((5 - 2))  # 输出 3
​
# 乘法
echo $((4 * 3))  # 输出 12
​
# 除法
echo $((8 / 2))  # 输出 4
​
# 取余
echo $((10 % 3))  # 输出 1

逻辑运算

逻辑运算在 Shell 脚本中常用于条件判断。

bashCopy Code# 逻辑非
var=0
if [ $((!var)) -eq 1 ]; then echo "var 为假,取反为真"; fi  # 输出 var 为假,取反为真
​
# 逻辑与
var1=1
var2=0
if [ $((var1 && var2)) -eq 1 ]; then echo "与运算为真"; else echo "与运算为假"; fi  # 输出 与运算为假
​
# 逻辑或
var1=1
var2=0
if [ $((var1 || var2)) -eq 1 ]; then echo "或运算为真"; fi  # 输出 或运算为真

比较运算

比较运算用于判断两个值的关系。

bashCopy Code# 小于
num1=3
num2=5
if [ $num1 -lt $num2 ]; then echo "num1 小于 num2"; fi  # 输出 num1 小于 num2
​
# 小于等于
num1=3
num2=3
if [ $num1 -le $num2 ]; then echo "num1 小于等于 num2"; fi  # 输出 num1 小于等于 num2

按位运算

按位运算在 Shell 中不常用,但可以通过$(( ))进行计算。

bashCopy Code# 按位与
num1=5  # 二进制:0101
num2=3  # 二进制:0011
echo $((num1 & num2))  # 输出 1,二进制:0001
​
# 按位或
echo $((num1 | num2))  # 输出 7,二进制:0111
​
# 按位取反
echo $((~num1))  # 输出 -6,注意这是补码表示
​
# 按位异或
echo $((num1 ^ num2))  # 输出 6,二进制:0110

运算符说明及常见运算命令(MD格式)

运算符说明

运算符 说明
+, -, *, /, % 加、减、乘、除、取余
!, &&, || 逻辑非(取反)、逻辑与(and)、逻辑或(or)
<, <=, >, >= 比较符号(小于、小于等于、大于、大于等于)
=, ==, != 赋值符号、等于、不等于
<<, >> 向左移位、向右移位
&, |, ~, ^ 按位与、按位或、按位取反、按位异或

常见运算命令(Markdown格式)

在Markdown中,虽然不直接支持数学运算,但可以通过特定格式展示运算命令及其说明。

命令 说明
() 常用于表示数学表达式中的括号,括号内的运算会优先执行。在Shell脚本中,可用于整数运算,括号内的$符号可省略,但赋值时需加上。
$[] Shell脚本中的整数运算并赋值命令。需与变量结合使用,用于存储运算结果。例如:a=$[3+4] 表示将7赋值给变量a。
expr Shell中的表达式求值命令,用于整数运算及其他功能。例如:expr 5 + 3 会返回8。注意,运算符与操作数之间需有空格。

注意‌:上述$[]expr命令为Shell脚本中的用法,Markdown本身不执行这些命令,但可通过代码块格式展示。

三、Shell 与运算符/命令的关系

在 Shell 环境中(如 Bash):

运算符直接使用

‌:

bashCopy Codeecho $((10 + 5))     # 算术运算 → 输出 15:ml-citation{ref="4,5" data="citationList"}
[ 5 -gt 3 ] && echo "成立"  # 逻辑运算 → 输出"成立":ml-citation{ref="5,8" data="citationList"}

命令解析执行

‌:

expr$[] 等命令由 Shell 解释并调用内核执行37。

脚本中的 iffor 等控制语句由 Shell 处理流程8。

四、典型应用场景示例

bashCopy Code#!/bin/bash
# 自动化备份脚本:ml-citation{ref="3,8" data="citationList"}
backup_dir="/home/user/docs"
target_dir="/backup"
if [ -d "$backup_dir" ]; then  # 检查目录存在
    tar -czf "$target_dir/backup_$(date +%F).tar.gz" "$backup_dir"  # 压缩备份
    echo "备份完成!":ml-citation{ref="5,8" data="citationList"}
else
    echo "目录不存在":ml-citation{ref="8" data="citationList"}
fi

expr 表达式计算工具使用说明及示例

expr 是一款强大的表达式计算工具,用于完成表达式的求值操作。以下是其使用规则及示例:

使用规则‌:

空格要求‌:表达式和运算符之间必须有空格,以确保正确解析。

反引号包含‌:完整的表达式需要被反引号 “ 包含起来。

乘号转义‌:乘号 (*) 前边必须加反斜杠 () 进行转义,避免与 shell 中的特殊含义冲突。

示例说明‌:

假设我们要计算表达式 2 + 3 * 4,按照上述规则,正确的输入方式如下:

shCopy Code
​
​
​
expr `2 + 3 * 4`

但注意,由于反引号会执行其中的命令并返回结果,而直接这样写会导致语法错误。实际上,我们应该先计算子表达式 3 * 4,然后再与 2 相加。但 expr 不支持直接计算带括号的表达式,所以我们需要分步进行,或者通过其他方式(如使用 $(( )))来计算。不过,为了说明转义和空格的要求,我们可以简化示例:

计算 3 * 4‌:

shCopy Code
​
​
​
expr 3 * 4

这将返回 12

再将结果与 2 相加‌(这里假设我们已经得到了 3 * 4 的结果):

shCopy Code
​
​
​
expr 2 + 12

这将返回 14

注意‌:在实际使用中,为了简化操作,通常会使用其他方式(如 $(( ))bc 命令)来进行复杂的数学运算。expr 更适合用于简单的算术运算和字符串操作。

条件测试(test)

语法格式‌:test <测试表达式>,其中 test<测试表达式> 中间至少有一个空格。

示例说明‌:

文件存在性测试‌:

bashCopy Code
​
​
​
test -e /etc/file1 && echo true || echo false  # 若 /etc/file1 文件存在,则输出 true,否则输出 false

表达式成功与否的测试‌:

若表达式成功(即文件存在):

bashCopy Code
​
​
​
test -e /etc/file1 && echo 1  # 输出 1

若表达式不成功(即文件不存在):

bashCopy Code
​
​
​
test -e /etc/file1 || echo 0  # 输出 0

其他用法示例‌:

数值比较‌:

bashCopy Codenum1=100
num2=50
if test $[num1] -eq $[num2]; then
    echo "num1 等于 num2"
else
    echo "num1 不等于 num2"
fi
# 输出:num1 不等于 num2

字符串比较‌:

bashCopy Codestr1="hello"
str2="world"
if test "$str1" = "$str2"; then
    echo "字符串相等"
else
    echo "字符串不相等"
fi
# 输出:字符串不相等

条件测试

条件测试语法‌:

语法格式:[<测试表达式>],内部的两端要有空格,和test命令等价。

示例‌:

[ -e /etc/file1 ] && echo true || echo false说明‌:若/etc/file1文件存在,则输出true,否则输出false

markdownCopy Code# 条件测试
​
在编程和脚本编写中,条件测试是非常重要的一环。以下是条件测试的基本语法和示例:
​
## 语法格式
​
`[<测试表达式>]`,其中测试表达式的两端需要有空格。这种格式与`test`命令是等价的。
​
## 示例
​
- 检查文件是否存在:
  ```bash
  [ -e /etc/file1 ] && echo true || echo false

如果/etc/file1文件存在,则输出true;否则,输出false

注意‌:在实际使用中,条件测试通常与if语句、循环等控制结构结合使用,以实现更复杂的逻辑判断。

测试表达式

数值比较参数

以下是数值比较的参数及其说明:

-eq‌:等于为真

-ne‌:不等于为真

-gt‌:大于为真

-ge‌:大于等于为真

-lt‌:小于为真(注意:图片中识别为-It,应为-lt)

-le‌:小于等于为真

字符串比较

字符串比较的参数及其说明如下:

=‌:等于为真(使用时需加双引号)

!=‌:不等于为真(使用时需加双引号)

-z‌:字符串长度为零则为真

-n‌:字符串长度不为零则为真

注意‌:字符串比较时,参数两端需加空格,且字符串需用双引号括起来。

文件比较

文件比较的参数及其说明:

-e‌:文件存在则为真

-f‌:文件存在且为普通文件则为真

-d‌:文件存在且为目录则为真

-x‌:文件存在且可执行则为真

-s‌:文件存在且至少有一个字符则为真

-c‌:文件存在且为字符型特殊文件则为真

-b‌:文件存在且为块特殊文件则为真

-r‌:文件存在且可读则为真

-w‌:文件存在且可写则为真

复杂逻辑判断

复杂逻辑判断的参数及其说明:

-a‌:条件同时成立为真

-o‌:任一条件成立为真

!‌:反向状态

以上内容已整理为Markdown格式,方便在支持Markdown的编辑器中查看和使用。

Shell测试表达式详解例子

一、基本语法结构

Shell测试表达式主要通过test命令或[]/[[]]实现条件判断:

bashCopy Code# 两种等效写法
test 表达式
[ 表达式 ]  # 注意方括号内必须加空格

二、字符串测试(带详细示例)

相等比较

bashCopy Codestr1="hello"
str2="world"
if [ "$str1" = "$str2" ]; then
  echo "字符串相等"
else
  echo "字符串不等"  # 会执行这里
fi

=比较内容是否相同

变量必须加双引号防止空值错误

空值检测

bashCopy Codeempty_str=""
if [ -z "$empty_str" ]; then
  echo "这是空字符串"  # 会执行
fi

-z检测长度为零的字符串

非空检测

bashCopy Codename="Alice"
if [ -n "$name" ]; then
  echo "欢迎, $name"  # 会执行
fi

-n检测非空字符串

三、数值比较(常用运算符)

运算符 说明 示例
-eq 等于 [ $a -eq 10 ]
-ne 不等于 [ $a -ne 20 ]
-gt 大于 [ $a -gt $b ]
-lt 小于 [ 5 -lt 10 ]
-ge 大于等于 [ $age -ge 18 ]

示例‌:

bashCopy Codecount=15
if [ $count -gt 10 ]; then
  echo "超过10个"
fi

四、文件测试(实用案例)

存在性检查

bashCopy Codeif [ -e "/etc/passwd" ]; then
  echo "文件存在"  # 会执行
fi

-e检测文件/目录是否存在

类型判断

bashCopy Codeif [ -d "/tmp" ]; then
  echo "这是个目录"
elif [ -f "/tmp/file.txt" ]; then
  echo "这是个普通文件"
fi

-d检测目录

-f检测普通文件

权限检查

bashCopy Codescript="/home/user/script.sh"
if [ -x "$script" ]; then
  echo "可执行"
fi

-x检测可执行权限

五、复合条件(逻辑组合)

与操作

bashCopy Codeif [ -f "data.txt" ] && [ -r "data.txt" ]; then
  echo "文件存在且可读"
fi

或操作

bashCopy Codeif [ "$OS" = "Linux" ] || [ "$OS" = "Darwin" ]; then
  echo "这是Unix-like系统"
fi

六、常见错误规避

空格缺失

bashCopy Code# 错误写法(缺少空格)
[$var="hello"]
​
# 正确写法
[ "$var" = "hello" ]  # 注意引号和空格

未引用的变量

bashCopy Code# 危险写法(空变量会导致语法错误)
[ $unset_var = "value" ]
​
# 安全写法
[ "${unset_var:-}" = "value" ]  # 使用默认值语法

字符串与数字混淆

bashCopy Code# 错误比较(用字符串运算符比较数字)
[ "10" -gt "2" ]  # 正确
[ "10" > "2" ]    # 错误(字典序比较)

七、完整示例脚本

bashCopy Code#!/bin/bash
​
# 字符串测试
read -p "输入用户名: " username
if [ -z "$username" ]; then
  echo "错误:用户名不能为空" >&2
  exit 1
elif [ "$username" = "admin" ]; then
  echo "管理员登录"
else
  echo "欢迎, $username"
fi
​
# 数值比较
age=25
if [ $age -lt 18 ]; then
  echo "未成年"
elif [ $age -ge 18 ] && [ $age -lt 60 ]; then
  echo "成年人"  # 会执行
else
  echo "老年人"
fi
​
# 文件检查
logfile="/var/log/app.log"
if [ ! -e "$logfile" ]; then
  touch "$logfile"
  chmod 644 "$logfile"
fi

if判断基础结构

‌:

markdownCopy Code```bash
if condition
then
    command
fi
textCopy Code

带else分支

‌:

markdownCopy Code```bash
if condition
then
    command
else
    command
fi
textCopy Code

含elif分支的复杂结构

‌:

markdownCopy Code```bash
if condition
then
    command
elif condition
then
    command
else
    command
fi

注意

‌:

condition

应替换为实际条件,

command

为执行命令。

Shell if判断详解

一、基础语法结构

Shell中的if判断有三种基本形式13:

单分支结构‌:

bashCopy Codeif [ 条件 ]
then
    执行语句
fi

双分支结构‌:

bashCopy Codeif [ 条件 ]
then
    条件成立时执行
else
    条件不成立时执行
fi

多分支结构‌:

bashCopy Codeif [ 条件1 ]
then
    条件1成立时执行
elif [ 条件2 ]
then
    条件2成立时执行
else
    所有条件都不成立时执行
fi

二、数值比较示例

数值比较必须使用特定运算符35:

运算符 说明 示例
-eq 等于 [ $a -eq $b ]
-ne 不等于 [ 5 -ne 3 ]
-gt 大于 [ $count -gt 10 ]
-lt 小于 [ $age -lt 18 ]
-ge 大于等于 [ $score -ge 60 ]
-le 小于等于 [ $temp -le 30 ]

实际应用示例‌:

bashCopy Code#!/bin/bash
age=20
if [ $age -lt 18 ]
then
    echo "未成年人"
elif [ $age -ge 18 ] && [ $age -lt 60 ]
then
    echo "成年人"
else
    echo "老年人"
fi

三、字符串比较示例

字符串比较注意事项14:

基本比较‌:

bashCopy Codename="Alice"
if [ "$name" = "Alice" ]; then
    echo "欢迎Alice"
fi

空值检测‌:

bashCopy Codeif [ -z "$unset_var" ]; then
    echo "变量未设置"
fi

非空检测‌:

bashCopy Codeif [ -n "$PATH" ]; then
    echo "PATH已设置"
fi

重要提示‌:字符串变量必须用双引号包裹,否则空变量会导致语法错误5。

四、文件测试示例

常用文件测试操作符47:

运算符 说明 示例
-e 文件/目录是否存在 [ -e "/tmp" ]
-f 是否是普通文件 [ -f "data.txt" ]
-d 是否是目录 [ -d "/home" ]
-r 是否可读 [ -r "config.ini" ]
-w 是否可写 [ -w "log.txt" ]
-x 是否可执行 [ -x "script.sh" ]
-s 文件大小是否大于0 [ -s "output.dat" ]

实际应用‌:

bashCopy Codeif [ -f "/etc/passwd" ] && [ -r "/etc/passwd" ]; then
    echo "密码文件存在且可读"
fi

五、逻辑运算符组合

if语句支持逻辑组合25:

逻辑与(&&)‌:

bashCopy Codeif [ $age -gt 18 ] && [ $gender = "male" ]; then
    echo "成年男性"
fi

逻辑或(||)‌:

bashCopy Codeif [ "$OS" = "Linux" ] || [ "$OS" = "Darwin" ]; then
    echo "Unix-like系统"
fi

逻辑非(!)‌:

bashCopy Codeif ! [ -f "/tmp/lock" ]; then
    touch "/tmp/lock"
fi

六、常见错误及解决方法

缺少空格‌:

bashCopy Code# 错误写法
if [$var="value"]
​
# 正确写法
if [ "$var" = "value" ]

未引用的变量‌:

bashCopy Code# 危险写法
if [ $unset_var = "test" ]
​
# 安全写法
if [ "${unset_var:-}" = "test" ]

混淆字符串和数字比较‌:

bashCopy Code# 错误比较
if [ "10" > "2" ]  # 字典序比较
​
# 正确比较
if [ 10 -gt 2 ]    # 数值比较

七、完整示例脚本

​
#!/bin/bash
​
# 检查root权限
if [ "$(id -u)" -ne 0 ]; then
    echo "请使用root权限运行此脚本" >&2
    exit 1
fi
​
# 检查操作系统
if [ -f "/etc/redhat-release" ]; then
    echo "检测到RedHat系系统"
elif [ -f "/etc/debian_version" ]; then
    echo "检测到Debian系系统"
else
    echo "未知操作系统"
fi
​
# 检查磁盘空间
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$disk_usage" -gt 90 ]; then
    echo "警告:根分区使用超过90%"
elif [ "$disk_usage" -gt 70 ]; then
    echo "注意:根分区使用超过70%"
else
    echo "磁盘空间正常"
fi

Shell case语句使用详解

一、基础语法结构

case语句是Shell脚本中用于多分支条件判断的结构,语法简洁高效,特别适合处理离散值匹配的场景(如菜单选择、参数解析等)12:

bashCopy Codecase 变量 in
    模式1)
        命令序列1
        ;;
    模式2|模式3)
        命令序列2
        ;;
    *)
        默认命令
        ;;
esac

变量‌:待匹配的变量或表达式

模式‌:支持通配符(*?[...])和逻辑或(|)

;;‌:结束当前分支(类似break)

*)‌:默认分支(类似default)

esac‌:case的反写,表示结构结束16

二、核心功能示例

1. 处理用户输入

bashCopy Code#!/bin/bash
echo -n "输入操作 (start/stop/restart): "
read action
​
case $action in
    start|s)
        echo "启动服务..."
        ;;
    stop|S)
        echo "停止服务..."
        ;;
    restart|r)
        echo "重启服务..."
        ;;
    *)
        echo "错误:未知操作!"
        exit 1
        ;;
esac

2. 文件类型判断

bashCopy Codefilename="image.jpg"
case $filename in
    *.jpg|*.jpeg)
        echo "JPEG 图片文件"
        ;;
    *.png)
        echo "PNG 图片文件"
        ;;
    *.gif)
        echo "GIF 动图文件"
        ;;
    *.pdf|*.docx)
        echo "文档文件"
        ;;
    *)
        echo "未知文件类型"
        ;;
esac

3. 数值范围判断

bashCopy Coderead -p "请输入分数(0-100): " score
case $score in
    9[0-9]|100)
        echo "优秀"
        ;;
    8[0-9])
        echo "良好"
        ;;
    7[0-9])
        echo "中等"
        ;;
    6[0-9])
        echo "及格"
        ;;
    [0-5][0-9])
        echo "不及格"
        ;;
    *)
        echo "无效分数"
        ;;
esac

三、高级用法技巧

1. 模式组合使用

bashCopy Coderead -p "输入颜色名称: " color
case $color in
    red|R*)  # 匹配red或以R开头的词
        echo "红色"
        ;;
    green|gr[ae]y)  # 匹配green或gray/grey
        echo "绿色/灰色"
        ;;
    blue|blu?)
        echo "蓝色"
        ;;
esac

2. 匹配范围表达式

bashCopy Coderead -p "输入字符: " char
case $char in
    [a-z])
        echo "小写字母"
        ;;
    [A-Z])
        echo "大写字母"
        ;;
    [0-9])
        echo "数字"
        ;;
    [[:punct:]])
        echo "标点符号"
        ;;
esac

3. 嵌套case语句

bashCopy Codecase $(uname -s) in
    Linux*)
        case $(lsb_release -i | awk '{print $3}') in
            Ubuntu)
                echo "Ubuntu系统"
                ;;
            CentOS)
                echo "CentOS系统"
                ;;
            *)
                echo "其他Linux发行版"
                ;;
        esac
        ;;
    Darwin*)
        echo "macOS系统"
        ;;
    *)
        echo "其他操作系统"
        ;;
esac

四、注意事项与最佳实践

模式匹配顺序‌ case语句按顺序匹配模式,第一个匹配成功的分支会被执行68

bashCopy Codecase $input in
    error)  # 具体值优先
        handle_error ;;
    err*)   # 通用匹配放后面
        handle_warning ;;
esac

默认分支处理‌ 总是包含*)分支处理意外情况8

bashCopy Codecase $choice in
    1) command1 ;;
    2) command2 ;;
    *) echo "无效选项"; exit 1 ;;
esac

变量引号处理‌ 当变量可能包含空格时使用双引号5

bashCopy Codecase "$user_input" in  # 正确写法
    "hello world")
        ...

空命令处理‌ 若某分支不需要执行命令,可直接使用;;

bashCopy Codecase $debug in
    true)
        # 空分支,跳过
        ;;
    *)
        echo "生产模式"
        ;;
esac

五、完整实用脚本示例

bashCopy Code#!/bin/bash
# 系统服务管理脚本
service=$1
action=$2
​
case "$service" in
    nginx|web)
        case "$action" in
            start)
                systemctl start nginx
                ;;
            stop)
                systemctl stop nginx
                ;;
            restart)
                systemctl restart nginx
                ;;
            status)
                systemctl status nginx
                ;;
            *)
                echo "Usage: $0 nginx {start|stop|restart|status}"
                exit 1
                ;;
        esac
        ;;
    mysql|db)
        case "$action" in
            start)
                systemctl start mysqld
                ;;
            # ... 类似nginx的操作
        esac
        ;;
    *)
        echo "未知服务: $service"
        echo "可用服务: nginx, mysql"
        exit 2
        ;;
esac

Shell for循环详解

一、基础语法结构

Shell中的for循环主要有三种形式,适用于不同场景13:

1. 标准列表循环(最常用)

bashCopy Codefor 变量 in 值1 值2 值3... 值N
do
    循环体命令
done

示例‌:

bashCopy Codefor fruit in apple banana orange
do
    echo "我喜欢吃$fruit"
done

2. C语言风格循环

bashCopy Codefor ((初始值; 条件判断; 值变化))
do
    循环体命令
done

示例‌:

bashCopy Codefor ((i=1; i<=5; i++))
do
    echo "这是第$i次循环"
done

3. 无限循环(需配合break使用)

bashCopy Codefor ((;;))
do
    循环体命令
    [ 条件 ] && break
done

二、核心使用场景

1. 遍历文件

bashCopy Code# 遍历当前目录所有.txt文件
for file in *.txt
do
    echo "处理文件: $file"
    wc -l "$file"
done

2. 数字范围遍历

bashCopy Code# 方法1:使用seq命令
for i in $(seq 1 10)
do
    echo $i
done
​
# 方法2:使用花括号扩展
for i in {1..10}
do
    echo $i
done
​
# 带步长的遍历
for i in {1..10..2}  # 1,3,5,7,9
do
    echo $i
done

3. 遍历命令输出

bashCopy Code# 遍历系统用户
for user in $(cut -d: -f1 /etc/passwd | head -5)
do
    echo "系统用户: $user"
done

三、循环控制语句

1. break – 跳出循环

bashCopy Codefor i in {1..100}
do
    if [ $i -eq 50 ]
    then
        echo "达到50,终止循环"
        break
    fi
    echo $i
done

2. continue – 跳过本次循环

bashCopy Codefor num in {1..10}
do
    if [ $((num % 2)) -eq 0 ]
    then
        continue  # 跳过偶数
    fi
    echo "奇数: $num"
done

3. exit – 退出整个脚本

bashCopy Codefor file in *
do
    if [ ! -f "$file" ]
    then
        echo "发现非文件项,终止脚本"
        exit 1
    fi
    echo "处理文件: $file"
done

四、高级用法技巧

1. 嵌套循环

bashCopy Codefor i in {1..3}
do
    echo "外层循环 $i"
    for j in A B C
    do
        echo "  内层循环 $j"
    done
done

2. 遍历数组

bashCopy Codecolors=("红" "绿" "蓝" "黄")
for color in "${colors[@]}"
do
    echo "颜色: $color"
done

3. 带索引的遍历

bashCopy Codearr=("苹果" "香蕉" "橙子")
for ((i=0; i<${#arr[@]}; i++))
do
    echo "第$i个元素: ${arr[$i]}"
done

五、常见错误与解决方法

空格问题‌:

bashCopy Code# 错误写法(变量未加引号)
for file in $files
​
# 正确写法
for file in "$files"

通配符扩展‌:

bashCopy Code# 当没有匹配文件时会直接使用通配符字符
for file in *.log
do
    [ -e "$file" ] || continue  # 跳过不存在的文件
    echo "处理: $file"
done

变量作用域‌:

bashCopy Codesum=0
for num in {1..100}
do
    ((sum+=num))  # 需要使用(( ))进行算术运算
done
echo "总和: $sum"

六、完整实用脚本示例

bashCopy Code#!/bin/bash
# 批量重命名脚本:为所有.jpg文件添加日期前缀
​
date=$(date +%Y%m%d)
count=1
​
for file in *.jpg
do
    if [ ! -f "$file" ]; then
        echo "没有找到jpg文件"
        exit 1
    fi
    
    newname="${date}_${count}.jpg"
    mv "$file" "$newname"
    echo "已重命名: $file -> $newname"
    ((count++))
done
​
echo "共处理了$((count-1))个文件"

Shell while循环详解

一、基础语法结构

while循环是Shell脚本中用于条件循环的结构,当条件为真时持续执行循环体13:

bashCopy Codewhile [ 条件 ]
do
    循环体命令
done

或者使用双括号进行算术条件判断:

bashCopy Codewhile (( 算术条件 ))
do
    循环体命令
done

二、核心使用场景

1. 条件循环

bashCopy Codecount=1
while [ $count -le 5 ]
do
    echo "循环次数: $count"
    ((count++))
done

2. 读取文件内容

bashCopy Codewhile read line
do
    echo "行内容: $line"
done < filename.txt

3. 无限循环(需配合break)

bashCopy Codewhile true
do
    echo "按Ctrl+C退出"
    sleep 1
done

三、循环控制语句

1. break – 跳出循环

bashCopy Codenum=1
while [ $num -lt 100 ]
do
    if [ $num -eq 50 ]
    then
        echo "达到50,终止循环"
        break
    fi
    echo $num
    ((num++))
done

2. continue – 跳过本次循环

bashCopy Codei=0
while [ $i -lt 10 ]
do
    ((i++))
    if [ $((i % 2)) -eq 0 ]
    then
        continue  # 跳过偶数
    fi
    echo "奇数: $i"
done

四、高级用法技巧

1. 多条件组合

bashCopy Codea=1
b=10
while [ $a -lt 10 ] && [ $b -gt 0 ]
do
    echo "a=$a, b=$b"
    ((a++))
    ((b--))
done

2. 管道输入处理

bashCopy Codels -l | while read perms links owner group size month day time filename
do
    echo "文件 $filename 大小: $size"
done

3. 菜单选择循环

bashCopy Codewhile :
do
    echo "1. 查看时间"
    echo "2. 查看日历"
    echo "3. 退出"
    read -p "请选择: " choice
    
    case $choice in
        1) date ;;
        2) cal ;;
        3) break ;;
        *) echo "无效选择" ;;
    esac
done

五、常见错误与解决方法

死循环问题‌:

bashCopy Code# 错误写法(条件永远不会变)
var=1
while [ $var -lt 10 ]
do
    echo "死循环"
done
​
# 正确写法
var=1
while [ $var -lt 10 ]
do
    echo "正常循环"
    ((var++))
done

条件格式错误‌:

bashCopy Code# 错误写法(缺少空格)
while [$var -lt 10]
​
# 正确写法
while [ $var -lt 10 ]

变量作用域问题‌:

bashCopy Code# 管道中的变量修改不会影响外部
var=0
seq 1 10 | while read num
do
    ((var++))  # 这个修改只在子shell有效
done
echo "实际值: $var"  # 输出0

六、完整实用脚本示例

bashCopy Code#!/bin/bash
# 猜数字游戏
​
target=$((RANDOM % 100 + 1))
attempts=0
​
while true
do
    read -p "猜一个1-100的数字: " guess
    ((attempts++))
    
    if [ $guess -eq $target ]; then
        echo "恭喜!你在$attempts次尝试后猜中了"
        break
    elif [ $guess -lt $target ]; then
        echo "太小了"
    else
        echo "太大了"
    fi
done

Shell函数详解

一、函数基础概念

Shell函数是将一组命令封装成可重复调用的代码块,用于实现代码复用和模块化编程19。主要特点包括:

减少重复代码

提高脚本可读性

便于维护和调试

支持参数传递和返回值

二、函数定义与调用

1. 定义方式

bashCopy Code# 标准写法
function 函数名 {
    命令序列
    [return 返回值]
}
​
# 简化写法1
函数名() {
    命令序列
}
​
# 简化写法2(不推荐)
function 函数名() {
    命令序列
}

2. 调用方式

bashCopy Code函数名          # 无参调用
函数名 参数1 参数2  # 带参调用

示例‌:

bashCopy Code# 定义欢迎函数
welcome() {
    echo "欢迎, $1!"
}
​
# 调用函数
welcome "张三"  # 输出:欢迎, 张三!

三、参数传递机制

1. 位置参数

$1:第一个参数

$2:第二个参数

$9:第九个参数(第10+参数需用${10}形式)

2. 特殊变量

$#:参数个数

$@:所有参数(保持独立)

$*:所有参数(合并为单个字符串)

示例‌:

bashCopy Codeshow_args() {
    echo "参数个数: $#"
    echo "第一个参数: $1"
    echo "所有参数: $@"
}
​
show_args A B C
# 输出:
# 参数个数: 3
# 第一个参数: A
# 所有参数: A B C

四、变量作用域

1. 局部变量

使用local关键字声明,仅在函数内有效210

bashCopy Codefunc() {
    local var="局部变量"
    global_var="全局变量"
}
​
func
echo $var       # 空值(局部变量不可见)
echo $global_var # 输出:全局变量

2. 环境变量

使用export声明,可被子进程继承

bashCopy Codeset_var() {
    export DB_HOST="localhost"
}

五、返回值处理

1. 状态返回值(0-255)

默认返回最后一条命令的退出状态

使用return N显式返回(0表示成功,非0表示失败)411

bashCopy Codecheck_file() {
    [ -f "$1" ] && return 0 || return 1
}
​
check_file "/etc/hosts"
if [ $? -eq 0 ]; then
    echo "文件存在"
fi

2. 返回数据

通过echo输出结果,调用时用$(...)捕获12

bashCopy Codeget_sum() {
    echo $(($1 + $2))
}
​
result=$(get_sum 10 20)
echo "结果: $result"  # 输出:结果: 30

六、高级用法

1. 递归函数

bashCopy Codefactorial() {
    if [ $1 -le 1 ]; then
        echo 1
    else
        local prev=$(factorial $(($1 - 1)))
        echo $(($1 * prev))
    fi
}
​
echo "5的阶乘是: $(factorial 5)"

2. 返回复杂数据

bashCopy Codeget_user_info() {
    echo "姓名: $1"
    echo "年龄: $2"
    echo "城市: $3"
}
​
# 读取多行输出到数组
mapfile -t info < <(get_user_info "李四" 25 "北京")
echo "${info[1]}"  # 输出:年龄: 25

七、实用示例脚本

​
#!/bin/bash
​
# 定义备份函数
backup_files() {
    local src_dir=$1
    local dest_dir=$2
    local date=$(date +%Y%m%d)
    
    [ ! -d "$src_dir" ] && { echo "源目录不存在"; return 1; }
    mkdir -p "$dest_dir" || { echo "无法创建目标目录"; return 2; }
    
    tar -czf "${dest_dir}/backup_${date}.tar.gz" "$src_dir" && 
    echo "备份成功: ${dest_dir}/backup_${date}.tar.gz"
}
​
# 调用示例
backup_files "/home/user/docs" "/backups"

Shell数据流重定向详解

一、基础概念

数据流重定向是Shell中控制输入/输出流向的重要机制,主要涉及三个标准数据流13:

标准输入(stdin)‌:文件描述符0,默认来自键盘

标准输出(stdout)‌:文件描述符1,默认输出到终端

标准错误(stderr)‌:文件描述符2,默认输出到终端

二、输出重定向

1. 覆盖输出到文件

bashCopy Code命令 > 文件      # 标准输出覆盖写入
命令 2> 文件     # 标准错误覆盖写入
命令 &> 文件     # 标准输出和错误都覆盖写入

示例‌:

bashCopy Codels > filelist.txt       # 将ls结果写入文件
gcc test.c 2> errors.log # 将编译错误写入日志

2. 追加输出到文件

bashCopy Code命令 >> 文件     # 标准输出追加写入
命令 2>> 文件    # 标准错误追加写入
命令 &>> 文件    # 标准输出和错误都追加写入

示例‌:

bashCopy Codedate >> log.txt        # 追加日期到日志
ping example.com &>> network.log # 记录全部输出

三、输入重定向

1. 从文件读取输入

bashCopy Code
​
​
​
命令 < 文件      # 从文件获取标准输入

示例‌:

bashCopy Codewc -l < /etc/passwd  # 统计文件行数
sort < unsorted.txt > sorted.txt # 排序文件

2. Here Document

bashCopy Code命令 << 结束标记
输入内容
结束标记

示例‌:

bashCopy Codemail -s "提醒" user@example.com << EOF
亲爱的用户:
您的备份已完成。
系统管理员
EOF

3. Here String

bashCopy Code
​
​
​
命令 <<< "字符串"

示例‌:

bashCopy Code
​
​
​
grep "error" <<< "This is an error message"

四、管道操作

1. 基本管道

bashCopy Code
​
​
​
命令1 | 命令2    # 将命令1的输出作为命令2的输入

示例‌:

bashCopy Codeps aux | grep python  # 查找Python进程
cat access.log | awk '{print $1}' | sort | uniq -c # 统计IP访问次数

2. 多级管道

bashCopy Code
​
​
​
命令1 | 命令2 | 命令3 | ... | 命令N

示例‌:

bashCopy Code
​
​
​
dmesg | grep -i error | less  # 分页查看系统错误日志

五、高级重定向技巧

1. 文件描述符操作

bashCopy Code命令 M>&N      # 将描述符M重定向到N
命令 M<> 文件   # 以读写方式打开文件到描述符M

示例‌:

bashCopy Codecommand 2>&1          # 将标准错误重定向到标准输出
exec 3<> datafile     # 打开文件到描述符3

2. 丢弃输出

bashCopy Code命令 > /dev/null      # 丢弃标准输出
命令 2> /dev/null     # 丢弃标准错误
命令 &> /dev/null     # 丢弃所有输出

示例‌:

bashCopy Code
​
​
​
nohup server.sh &> /dev/null &  # 后台运行并丢弃输出

3. 重定向组合

bashCopy Code命令 > 文件 2>&1      # 标准输出和错误都写入文件
命令 >> 文件 2>&1     # 标准输出和错误都追加到文件

示例‌:

bashCopy Code
​
​
​
./install.sh > install.log 2>&1  # 记录安装日志和错误

六、实用脚本示例

​
#!/bin/bash
# 分析日志文件中的错误和警告
​
LOG_FILE="/var/log/syslog"
ERROR_FILE="errors.log"
WARNING_FILE="warnings.log"
​
# 清空旧日志
> "$ERROR_FILE"
> "$WARNING_FILE"
​
# 提取错误和警告
grep -i "error" "$LOG_FILE" >> "$ERROR_FILE"
grep -i "warning" "$LOG_FILE" >> "$WARNING_FILE"
​
# 统计结果
echo "错误统计: $(wc -l < "$ERROR_FILE") 条"
echo "警告统计: $(wc -l < "$WARNING_FILE") 条"

七、常见错误与解决

覆盖重要文件‌:

bashCopy Code# 危险操作(会清空文件)
echo "test" > important.log
​
# 安全做法(先检查文件)
[ -f important.log ] && echo "文件已存在" || echo "test" > important.log

权限问题‌:

bashCopy Code# 错误:权限不足
echo "data" > /root/file
​
# 解决方案
sudo sh -c 'echo "data" > /root/file'

管道中断‌:

bashCopy Code# 错误:管道右侧命令失败
cat file | nonexistent_command
​
# 解决方案
cat file | grep "pattern" || echo "命令执行失败"

Shell printf命令详解

一、printf基础概念

printf是Shell中用于格式化输出的命令,相比echo命令提供了更精确的输出控制23。主要特点包括:

支持多种数据类型格式化输出

可以精确控制对齐方式和宽度

不会自动添加换行符(需手动添加

语法与C语言的printf函数类似

二、基本语法结构

bashCopy Code
​
​
​
printf "格式字符串" 参数1 参数2 ...

示例‌:

bashCopy Code
​
​
​
printf "Hello, %s
" "World"  # 输出:Hello, World

三、常用格式说明符

说明符 用途 示例 输出示例
%s 字符串 printf "%s" "abc" abc
%d 十进制整数 printf "%d" 123 123
%f 浮点数 printf "%f" 3.14 3.140000
%c 单个字符 printf "%c" 65 A
%x 十六进制小写 printf "%x" 255 ff
%X 十六进制大写 printf "%X" 255 FF
%o 八进制 printf "%o" 8 10
%b 解释反斜杠转义字符 printf "%b" "a b" a b
%% 百分号本身 printf "%d%%" 50 50%

四、格式化控制

1. 宽度控制

bashCopy Codeprintf "%10s
" "hello"   # 右对齐,宽度10
printf "%-10s
" "hello"  # 左对齐,宽度10

2. 精度控制

bashCopy Codeprintf "%.2f
" 3.14159   # 输出:3.14
printf "%5.2f
" 3.14159  # 输出: 3.14(总宽度5,小数2位)

3. 组合使用

bashCopy Code
​
​
​
printf "%-10s %5.2f
" "Apple" 2.5  # 输出:Apple       2.50

五、转义序列

printf支持的常见转义序列5:


– 换行

– 水平制表符

– 退格


– 回车

\ – 反斜杠

nnn – 八进制值

xHH – 十六进制值

示例‌:

bashCopy Code
​
​
​
printf "第一行
第二行
"  # 输出两行

六、实用示例

1. 表格输出

bashCopy Codeprintf "%-10s %-8s %-6s
" "姓名" "性别" "年龄"
printf "%-10s %-8s %-6d
" "张三" "男" 25
printf "%-10s %-8s %-6d
" "李四" "女" 30

2. 进度条显示

bashCopy Codefor i in {1..10}; do
    printf "[%-10s] %d%%
" $(printf "%${i}s" | tr ' ' '#') $((i*10))
    sleep 0.1
done
printf "
"

3. 颜色输出

bashCopy Codeprintf "33[31m红色文字33[0m
"      # 红色
printf "33[32;44m绿字蓝底33[0m
"  # 绿色文字,蓝色背景

七、与echo的区别

特性 printf echo
自动换行 不会(需加
会自动换行
格式化 支持 不支持
转义字符 默认解释 需-e选项
移植性 更好(POSIX) 不同系统有差异
变量扩展 支持 支持

示例对比‌:

bashCopy Codeecho "Hello	World"      # 输出:Hello	World
printf "Hello	World
"  # 输出:Hello    World

八、常见错误

忘记换行符‌:

bashCopy Codeprintf "没有换行"  # 提示符会紧接输出
printf "有换行
"  # 正确写法

参数与格式不匹配‌:

bashCopy Code
​
​
​
printf "%d
" "abc"  # 错误:期望数字但得到字符串

引号使用不当‌:

bashCopy Codeprintf %s hello      # 能工作但不推荐
printf "%s" "hello"  # 推荐写法

Linux GCC基本使用指南

一、GCC简介

GCC(GNU Compiler Collection)是GNU开发的编译器套件,支持多种编程语言编译,包括C、C++、Objective-C、Fortran、Ada等34。最初代表GNU C Compiler,现已发展为GNU编译器集合89。

二、安装GCC

在大多数Linux发行版中,GCC通常已预装。可通过以下命令检查:

bashCopy Code
​
​
​
gcc --version

若未安装,使用以下命令安装:

bashCopy Code# Ubuntu/Debian
sudo apt install gcc
​
# CentOS/RHEL
sudo yum install gcc

三、基本编译流程

1. 单文件编译

bashCopy Codegcc hello.c -o hello  # 编译hello.c生成可执行文件hello
./hello               # 运行程序

2. 分步编译过程18

预处理

‌:处理宏定义、头文件等

bashCopy Code
​
​
​
gcc -E hello.c -o hello.i

编译

‌:生成汇编代码

bashCopy Code
​
​
​
gcc -S hello.i -o hello.s

汇编

‌:生成目标文件

bashCopy Code
​
​
​
gcc -c hello.s -o hello.o

链接

‌:生成可执行文件

bashCopy Code
​
​
​
gcc hello.o -o hello

四、常用编译选项

选项 说明 示例
-o 指定输出文件名 gcc hello.c -o hello
-c 只编译不链接 gcc -c hello.c
-g 生成调试信息 gcc -g hello.c
-Wall 启用所有警告 gcc -Wall hello.c
-O 优化级别(0-3) gcc -O2 hello.c
-I 添加头文件路径 gcc -I./include hello.c
-L 添加库文件路径 gcc -L./lib hello.c
-l 链接指定库 gcc hello.c -lm

五、多文件编译

1. 直接编译多个文件26

bashCopy Code
​
​
​
gcc main.c utils.c -o program

2. 分别编译后链接

bashCopy Codegcc -c main.c
gcc -c utils.c
gcc main.o utils.o -o program

六、静态库与动态库

1. 创建静态库

bashCopy Codegcc -c lib.c -o lib.o
ar rcs libmylib.a lib.o

2. 使用静态库

bashCopy Code
​
​
​
gcc main.c -L. -lmylib -o program

3. 创建动态库

bashCopy Code
​
​
​
gcc -shared -fPIC lib.c -o libmylib.so

4. 使用动态库

bashCopy Codegcc main.c -L. -lmylib -o program
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

七、实用示例

1. 带调试信息的编译

bashCopy Code
​
​
​
gcc -g -Wall program.c -o program

2. 优化编译

bashCopy Code
​
​
​
gcc -O3 -march=native program.c -o program

3. 查看预处理结果

bashCopy Code
​
​
​
gcc -E program.c | less

八、常见问题

头文件找不到‌:使用-I选项指定路径

库文件找不到‌:使用-L指定路径,-l指定库名

版本不兼容‌:使用-std=指定标准,如-std=c11

权限问题‌:使用sudo或检查文件权限

一、GCC编译四阶段

GCC将编译过程分为四个核心阶段,可通过命令选项分步查看:

预处理(Preprocessing)

作用‌:处理宏定义、头文件包含、条件编译等

命令‌:gcc -E hello.c -o hello.i

操作

‌:

展开#include的头文件内容

替换#define定义的宏

删除注释

处理条件编译指令(如#ifdef)13

编译(Compilation)

作用‌:将预处理后的代码转换为汇编语言

命令‌:gcc -S hello.i -o hello.s

操作

‌:

语法和语义检查

生成与CPU架构相关的汇编代码

代码优化(如使用-O2选项)36

汇编(Assembly)

作用‌:将汇编代码转为机器码(二进制目标文件)

命令‌:gcc -c hello.s -o hello.o

输出‌:生成.o目标文件(不可直接执行)16

链接(Linking)

作用‌:合并目标文件和库函数,生成可执行文件

命令‌:gcc hello.o -o hello

操作

‌:

解析函数调用(如printf

链接标准库(如libc.so

地址重定位36


二、单命令完成全流程

bashCopy Code
​
​
​
gcc hello.c -o hello  # 一步完成预处理→编译→汇编→链接

默认输出文件名为a.out(未指定-o时)14


三、关键编译选项详解

选项 作用 示例
-o <file> 指定输出文件名 gcc hello.c -o hello
-c 只编译不链接(生成.o文件) gcc -c hello.c
-I<dir> 添加头文件搜索路径 gcc -I./include main.c
-l<lib> 链接指定库(如数学库-lm gcc calc.c -lm
-Wall 启用所有编译警告 gcc -Wall test.c
-g 生成调试信息(用于GDB) gcc -g debug.c
-O<level> 优化级别(0-3,如-O2 gcc -O2 optimize.c 47

四、多文件编译示例

bashCopy Code# 方法1:直接编译所有源文件  
gcc main.c utils.c -o program  
​
# 方法2:分步编译后链接  
gcc -c main.c        # 生成 main.o  
gcc -c utils.c       # 生成 utils.o  
gcc main.o utils.o -o program  # 链接

五、常见问题解决

头文件找不到

使用-I指定路径:gcc -I/usr/local/include main.c

或设置环境变量:export C_INCLUDE_PATH=/path/to/include1112

库文件找不到

-L指定库路径:gcc -L./lib main.c -lmylib

运行时需设置:export LD_LIBRARY_PATH=./lib1112

链接错误

检查函数名拼写

确认库是否安装(如数学库需加-lm)10

GCC编译选项详解

编译过程控制

-c‌:只编译不链接,将.c文件生成.o为目标文件,常用于编译不包含主程序的子程序文件。

-S‌:只编译到汇编阶段,不汇编和链接,生成汇编代码文件。

-E‌:只进行预处理,不编译、汇编和链接,生成预处理后的文件。

输出文件控制

-o outname‌:指定输出文件的名称为outname,不能与源文件同名。默认输出为a.out

调试与优化

-g‌:生成调试信息,用于GNU的gdb调试工具。等级可选-g1(基本)、-g2(默认)、-g3(包含宏信息)。

-O‌:对程序进行优化编译链接,提高可执行文件效率,但减慢编译速度。常用等级有-O0(无优化)、-O1-O2-O3

-Werror‌:将所有警告转换为错误,遇到警告即终止编译。

目录与库搜索

-I dirname‌:将dirname目录加入头文件搜索路径,用于预编译阶段。

-L dirname‌:将dirname目录加入库文件搜索路径。

-l FOO‌:链接名为libFOO的函数库。

链接控制

-static‌:链接静态库,而非动态库。

语言与标准

-ansi‌:支持ANSI/ISO C标准语法,取消GNU语法中的冲突部分。

-std=标准‌:指定C或C++语言标准,如-std=c11-std=c++20

警告与错误处理

-w‌:关闭所有警告,不建议使用。

-W‌:开启所有gcc提供的警告(注意:此选项在标准gcc中可能不直接存在,但表示开启警告的意图)。

-v‌:显示执行的详细过程及gcc版本号。

其他常用选项

-D宏定义‌:定义宏,如-DPI=3.14

-U宏名‌:取消宏定义。

-march=架构‌:针对特定CPU架构进行优化。

-fstack-protector‌:启用栈保护,增强安全性。

静态与动态链接库详解

一、基本概念

链接库是将可复用代码打包的二进制文件,主要分为两种类型:

静态链接库‌(Static Library)

Linux下扩展名为.a(Archive)

Windows下扩展名为.lib

特点‌:编译时完整拷贝到可执行文件中13

动态链接库‌(Dynamic Library)

Linux下扩展名为.so(Shared Object)

Windows下扩展名为.dll

特点‌:运行时动态加载到内存36

二、核心区别对比

特性 静态库 动态库
链接时机 编译时链接 运行时链接
文件独立性 可执行文件独立运行 需依赖外部库文件
内存占用 多进程重复加载,占用高 多进程共享,占用低
更新维护 需重新编译整个程序 只需替换库文件
加载速度 启动快(无运行时加载) 启动稍慢(需解析符号)
典型应用 嵌入式系统、独立工具 大型软件、系统组件 13

三、静态库工作原理

创建流程

‌:

bashCopy Codegcc -c lib.c        # 生成lib.o
ar rcs libmylib.a lib.o  # 打包为静态库

使用方式

‌:

bashCopy Code
​
​
​
gcc main.c -L. -lmylib -o program

特点

‌:

代码被完整复制到最终可执行文件

更新库需重新编译所有依赖程序

适合小型工具或对独立性要求高的场景13

四、动态库工作原理

创建流程

‌:

bashCopy Code
​
​
​
gcc -shared -fPIC lib.c -o libmylib.so

使用方式

‌:

bashCopy Codegcc main.c -L. -lmylib -o program
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

特点

‌:

多个程序共享同一内存中的库代码

支持热更新(替换.so文件即可)

需处理版本兼容性问题36

常见问题注意‌:

动态库路径问题:通过LD_LIBRARY_PATH/etc/ld.so.conf配置

版本冲突:使用soname机制管理版本

符号冲突:静态库可能出现重复定义错误

静态库和动态库创建与使用实例教程

静态库创建与使用

1. 创建静态库

​
// 加法函数
int add(int a, int b) {
    return a + b;
}
​
// 减法函数
int subtract(int a, int b) {
    return a - b;
}
 编译为目标文件
gcc -c math_utils.c -o math_utils.o
​
# 创建静态库
ar rcs libmath.a math_utils.o
​
# 查看库内容
ar -t libmath.a

2. 使用静态库

 <stdio.h>
​
// 声明外部函数
extern int add(int, int);
extern int subtract(int, int);
​
int main() {
    printf("5 + 3 = %d
", add(5, 3));
    printf("5 - 3 = %d
", subtract(5, 3));
    return 0;
}
​
# 编译并链接静态库
gcc main.c -L. -lmath -o calculator
​
# 运行程序
./calculator
​

动态库创建与使用

1. 创建动态库

#include <string.h>
​
// 字符串反转函数
void reverse_string(char* str) {
    int n = strlen(str);
    for (int i = 0; i < n / 2; i++) {
        char temp = str[i];
        str[i] = str[n - i - 1];
        str[n - i - 1] = temp;
    }
}
 编译为位置无关代码
gcc -fPIC -c string_utils.c -o string_utils.o
​
# 创建动态库
gcc -shared -o libstr.so string_utils.o
​
# 查看动态库依赖
ldd libstr.so
​

2. 使用动态库

#include <stdio.h>
#include <string.h>
​
// 声明外部函数
extern void reverse_string(char*);
​
int main() {
    char text[100] = "Hello, World!";
    printf("Original: %s
", text);
​
    reverse_string(text);
    printf("Reversed: %s
", text);
​
    return 0;
}
​
 编译并链接动态库
gcc app.c -L. -lstr -o string_app
​
# 设置库路径并运行
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./string_app
​

关键说明

静态库特点:

编译时完整嵌入可执行文件

程序可独立运行

更新需重新编译整个程序

动态库特点:

运行时加载

多个程序可共享

更新只需替换库文件

需设置LD_LIBRARY_PATH或安装到系统目录

常见问题解决:

找不到库:检查路径和LD_LIBRARY_PATH

版本冲突:使用版本号命名库文件

符号未定义:确保所有函数都有实现

tftp安装搭建

NFS服务安装和搭建

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容