共享文件夹的路径 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
功能:在某些系统中,adduser是useradd的友好前端,用于添加用户
基本语法: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:指定文件系统类型,如 ext4、ntfs、vfat 等。
-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 命令的版本信息。
注意事项:
在卸载文件系统之前,确保没有进程正在使用该文件系统,否则卸载可能失败。
使用 lsof 或 fuser 命令可以查看哪些进程在使用某个挂载点,便于及时处理。
文件系统特性详解
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.sh或source script.sh。
总结:
子shell执行:适用于需要隔离环境的场景,变量和环境设置在子shell中局部生效。
当前shell执行:适用于需要保留变量和修改当前shell环境的场景。
shell变量详解
什么是shell变量
变量是编程中用于存放数据的容器。在Shell脚本中,变量同样扮演着至关重要的角色,用于存储和引用数据。Shell变量无需事先声明类型,直接赋值即可使用,这符合Shell作为弱类型语言的特性。
shell变量的命名规则
组成:变量名由字母、数字和下划线组成。
开头:自定义变量必须以字母或下划线开头,不能是数字。
限制:不能使用Shell中的保留关键字,如$、#、?等。
shell变量的定义与赋值
赋值:使用=号进行赋值,如变量名=变量值。
引号:变量值可以加上单引号或双引号,特别是当值中包含空格或特殊字符时。
空格:=两侧不能有空白符号,如空格或tab。
shell变量的类型与操作
类型:虽然Shell不强制要求变量类型,但根据用途可分为字符串变量、数值变量、环境变量等。
操作:包括变量替换、变量修改(如搜索和替换)、获取变量长度等。
shell变量的特殊用法
环境变量:由操作系统提供,用于配置程序环境,如PATH、HOME等。
位置参数:执行脚本时传递给脚本的参数,可通过$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。
脚本中的 if、for 等控制语句由 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.a2. 使用静态库
<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
版本冲突:使用版本号命名库文件
符号未定义:确保所有函数都有实现





















暂无评论内容