# 1.1 GNU C Complier

程序 g++ 是将 gcc 默认语言设为 C++ 的一个特殊的版本,链接时它自动使用 C++ 标准库而不用 C 标准库。

gcc 头文件搜索路径:

  1. 当前目录
  2. 手动指定的目录
  3. gcc 环境变量设置 CPATH,C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
  4. 系统标准 include 路径

gcc/g++指令选项 功 能

  • -E(大写) 预处理指定的源文件,不进行编译。
  • -S(大写) 编译指定的源文件,但是不进行汇编。
  • -c 编译、汇编指定的源文件,但是不进行链接。
  • -o 指定生成文件的文件名。
  • -llibrary 其中 library 表示要搜索的库文件的名称。该选项用于手动指定链接环节中程序可以调用的库文件。建议 -l 和库文件名之间不使用空格,比如 -lstdc++。
  • -print-search-dirs 查看 gcc 默认搜索路径。

注意,使用-l选项指明静态库的名字时,既不需要lib前缀,也不需要.a后缀,只能写 test,GCC 会自动加上前缀和后缀。

  • -L <path> 指定库路径。
  • -I <path> 指定头文件路径。
  • -ansi 对于 C 语言程序来说,其等价于 -std=c90;对于 C++ 程序来说,其等价于 -std=c++98。
  • -std= 手动指令编程语言所遵循的标准,例如 c89、c99、c++98、c++11 等。
  • -D 处理源文件前定义一个宏。
  • -U 取消宏定义。
  • -g 生成可调式文件。
  • -O2-O 更好的优化编译。
  • -MM 查看文件的依赖(非标准库)
  • Wall 打开所有警告。
  • Wextra 启用一些未由-Wall启用的额外警告标志。
  • Wvla 警告动态数组的使用。
  • Werror 把所有的警告当作错误处理。
  • static 强制使用同名静态库,并且链接到的所有库都用静态编译。谨慎使用。
  • -pedantic 以ANSI/ISO C标准列出的所有警告,使用了扩展语法的地方将会产生警告。
  • -ansi
  • -nostdlib 编译时不使用标准 C 库。
  • -Ttext 0 指定 0 地址。
  • -Iinclude -E hello.c 查看预处理结果
  • -march=native 允许编译器使用 cpu 完整的特性集,生成当前机器架构的最优指令,但是影响可执行文件的移植性。

//查看预处理的结果,比如头文件是哪个

gcc -Iinclude -E Hello.c

gcc -E -dM Hello.c > test.txt

objdump -D 反汇编。

链接指定的库:

-l:libxxx.a-l:libxxx.so.xxx

# 1.2 动态链接库和静态链接库

# 1.2.1 创建静态链接库

ar rcs + 静态库文件的名字 + 目标文件列表

ar rcs libtest.a *.o

ar 是 Linux 的一个备份压缩命令,它可以将多个文件打包成一个备份文件(也叫归档文件),也可以从备份文件中提取成员文件。ar 命令最常见的用法是将目标文件打包为静态链接库。

对参数的说明:

  • 参数 r 用来替换库中已有的目标文件,或者加入新的目标文件。
  • 参数 c 表示创建一个库。不管库否存在,都将创建。
  • 参数 s 用来创建目标文件索引,这在创建较大的库时能提高速度。
  • 参数 v
  • d 从归档文件中删除
  • t 查看归档文件的内容
  • x 解压归档文件
  • a/b 向归档文件中添加内容
  • v 显示详细信息

ar rcsv libxxx.a *.o

# 1.2.2 创建动态链接库

gcc 源文件(*.c) -c -fpic -Wall

gcc -shared 与位置无关的目标文件(*.o) -o 动态库(libxxx.so)

-fPIC 是创建与地址无关的编译程序(pic,position independent code),是为了能够在多个应用程序间共享。-shared 指定生成动态链接库。

态库必须拷贝放在/usr/lib目录或/lib目录中,才可以使用。如果不想拷贝的话,可以在之前系统lib目录下生成一个动态库的软链接。

# 发布
 	1. 提供头文件: xxx.h
 	2. 提供动态库: libxxx.so
1
2
3

动态库如果安装在/lib或者/usr/lib下,那么 ld 默认能够找到

或者将文件路径保存到 /etc/ld.so.conf 中。执行 ldconfig 命令,将 /etc/ld.so.conf 中保存的库路径写入 /etc/ld.so.cache

LD_LIBRARY_PATH 环境变量保存库路径。

可以使用 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/自己的目录 重新给链接库环境变量赋值。

ld.so 接口。

静态库和动态库的载入时间是不一样的。

静态库的代码在编译的过程中已经载入到可执行文件中,所以最后生成的可执行文件相对较大。

动态库的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,所以最后生成的可执行文件相对较小。

静态库和动态库的最大区别是,静态库链接的时候把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度和降低程序的耦合度。

# 1.3 GNU Symbolic Debugger

TODO: 多线程调试。

GDB调试主要有三种方式:

直接调试目标程序:gdb ./hello_server

附加进程id:gdb attach pid

如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他,如果GDB attach某个进程,退出GDB之前要用命令 detach 解除附加进程。

调试core文件:gdb filename corename

用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。

--core=COREFILE 调试时core dump的core文件。

gdb 内命令:

list 列出源文件,回车继续列出。

break num 在 num 行处设置断点。

break funcname 在函数入口处设置断点。

break filename:funcname

info break 查看断点信息。

run 运行程序。

next 单条语句执行

continue 继续运行程序直到下一个断点。

print 查看变量当前的值。

print param=value,用于在调试过程中修改变量的值;

print func(),输出func函数执行的结果,常见的用途是打印系统函数执行失败原因:print strerror(errno);

ptype val 打印变量类型。print type

step step in,如果有函数调用,他会进入该函数。

next step out,不会进入函数调用。

bt backtrace 查看函数堆栈。

f n frame 切换堆栈。

return val 命令是立即退出当前函数,剩下的代码不会执行了,return 还可以指定函数的返回值

finish 运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。

watch expr 设置观察点,expr 值变化时停住程序。awatch expr 当值被读或被写的时候停住程序。

watch *指针变量,监视的是指针所指的内容;

clear 清除所有停止点。clear num 清除指定行的停止点,clear filenam:linenum 清除指定文件指定行的停止点。

disable [breakpoints] [range...] 暂停所指定的停止点。

enable [breadpoints] [range...] 使能所有停止点。

quit 退出

# 1.4 包管理工具 apt 和 dpkg

# 1.4.1 软件源配置文件

/etc/apt/sources.list

软件源是指互联网中的众多服务器,这些服务器上存放了大量的软件包,可用于用户主机的更新和升级。

# 1.4.2 apt-get

apt-get 用于管理软件包,包括安装、卸载、升级等。

  • update 刷新软件源,下载更新软件包列表信息。
  • upgrade 将系统中所有软件包升级到最新版本。
  • install 下载所需软件包并进行安装配置。
  • remove 卸载软件包。
  • autoremove 将不满足依赖关系的软件包自动卸载。
  • source 下载源码包。
  • clean 删除缓存区中所有已下载的包文件。
  • autoclean 删除缓存区中老版本的已下载的包文件。
  • check 检查系统中依赖关系的完整性。
  • --purgeremove 一起使用,完全卸载软件包,同时删除该软件包所使用的配置文件。
  • -s 不做实际操作,只是模拟命令执行结果。
  • -f 修复系统中存在的软件包依赖性问题。

apt-get check apt-get -f install 通常作为组合命令使用,前者用于检查软件包依赖关系,后者用于修复依赖关系。

经常使用 apt-get update 刷新软件源可保持软件源最新。该命令会为服务器具有的软件包资源j

查询安装包大小:apt-cache show <package> | grep "Size"

# 1.4.3 dpkg

dpkg -r <package> 移除一个已安装的软件包。

dpkg -i <package> 离线安装。

dpkg -p <package> 移除已安装软件包以及配置文件。

dpkg -L <package> 列出安装的软件包清单。

dpkg-reconfigure <package> 重新配置一个已安装的软件包。

# 1.5 输入输出重定向

标准输入 0,默认是键盘,标准输出 1,默认是终端,标准错误输出 2,默认是终端。

command < filefile 重定向为输入源。

command > filefile 重定向为输出源。

command >> file ,将 file 重定向为输出源,追加模式。

command 2> filefile 重定向为标准错误源。

command 2>> filefile 重定向为标准错误源,追加模式。

command &>> filefile 重定向为标准输出源和标准错误源,等同于 >>& ,标准输出与标准错误输出全部重定向。

command >> file1 2>> file2file1 重定向为标准标准输出源,将 file2 重定向为标准错误。

command > file1 2>&1 将标准错误输出转成标准输出。

&> /dev/null 重定向到 null

输入输出重定向就是取代了键盘屏幕,能够接受键盘输入的都可以用重定向改为文件输入,能够输出到屏幕的,都可以通过重定向保存到文件。

而管道符可以把标准输出转标准输入,以让可以接受标准输入的命令可以以此为输入执行命令,所以说,重定向也可以做到同样的事情,但一般来说不会这么做,就像cat,默认以文件名为参数,没有文件名才从标准输入读。

定向的作用对象只能是文件。

# 1.6 常用命令

ls,cd,mv,cp,rm,mkdir,echo,date,pwd,clear,who,man,shutdown,passwd,su,top,pstree

  • who am i 等同于 who -m,只打印执行该命令的登录用户的信息
  • w, 系统当前所有的登录会话及所做的操作
  • who 系统当前所有的登录会话

# 1.6.1 cat

cat 等待输入,按<enter> 键后输出到标准输出。

cat < file 将file 的内容输出到标准输出。(默认是终端)

cat > file 将输入的内容重定向到 file 中。

# 1.6.2 less

是一个分页显示工具。

less 命令主要用于打开大文件,less 不会读取整个文件,相比于 vim 或 nano 等文本编辑器,加载时间会更快。

C-f 翻页,C-b 翻页。

-N 打印行号。

-m 显示百分比。

/<pattern> 搜索 <pattern>,操作使用 vi 模式。nN?

pa -aux | less

# 1.6.3 wahtis

等同于 man -f 。显示来自手册页的加简短说明(若有)。

# 1.6.4 mount

临时挂载分区

# 1.6.5 umount

卸载一个文件系统,就是从系统目录结构中,移去该指定的文件系统,卸载后的文件系统不能被用户使用。

# 1.6.6

# 1.6.7 du

du -sh

报告磁盘空间使用情况。

-h 以最常见的格式显示出大小。

-T 显示文件类型。

-h:以人类可读的方式显示

-a:显示目录占用的磁盘空间大小,还要显示其下目录和文件占用磁盘空间的大小

-s:显示目录占用的磁盘空间大小,不要显示其下子目录和文件占用的磁盘空间大小

-c:显示几个目录或文件占用的磁盘空间大小,还要统计它们的总和

–apparent-size:显示目录或文件自身的大小

-l :统计硬链接占用磁盘空间的大小

-L:统计符号链接所指向的文件占用的磁盘空间大小

# 1.6.8 df

报告文件系统磁盘空间的使用情况。

-T 输出文件类型。

-h 以最常见的格式显示出大小。

# 1.6.9 grep

-n 显示行号。

-v 改变匹配的意义,不显示匹配的行。通常配合使用:

pa -aux | grep -n xxx | grep -v "grep"

# 1.6.10 file

查看文件类型。

# 1.6.11 time

多次执行一个脚本。

time <可执行文件> [次数]

输出每次重复操作(iteration)所需时间的平均值,以微秒为单位。测量时间使用流(elapsed)时间,而不是 CPU 时间。

# 1.6.12 ls

列出目录内容。

-F 目录显示 / 后缀。

-l 显示文件详细信息

-a 显示所有隐藏文件

R 递归显示子目录所有内容。

i 显示 inode

-h 以最常见的格式显示出大小。

-d 查看目录自己的内容,而不是目录下的内容。

ls -alrF

# 1.6.13 tar

7z 和 zip 压缩格式都不能保留 unix 风格的文件权限,比如解压出个可执行文件要重新 chmod chown 才能恢复正常。而 tar 格式可以。而 tar 本身不提供压缩,无非就是把包括所有文件的內容和权限拼成一个文件而己,所以用另外如 gzip 格式压缩。

存储或提取 tar 文件的程序。

-f 指定存档或设备中的文件。

-zgzip 处理文档。

-x 从文档提取文件。

-c 创建一个新的文档。

-v 显示文件处理过程。

tar -xzvf 解压 tar.gz 文件。

tar -czvf 压缩为 tar.gz 文件。

xz 压缩效果最好,多线程压缩最快。

tar -cvf <压缩目标> | xz -T 0 -c > <压缩包名>.tar.xztar -I "xz -T0" -cvf <压缩包名>.tar.xz <压缩目标>

# 1.6.14 chmod

改变文件或目录的访问权限。

# 1.6.15 chgrp

改变文件或目录所属的组。

# 1.6.16 ln

在文件之间建立连接。

默认建立硬链接。

-s 建立软链接。

Linux 下的文件是通过索引节点(Inode)来识别文件,在 Linux 的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号 (Inode Number)。

在 Linux 中,多个文件名指向同一索引节点是存在的,所以硬连接指通过索引节点来进行的连接,即每一个硬链接都是一个指向对应区域的文件。

文件系统会维护一个引用计数,只要有文件指向这个区块,它就不会从硬盘上消失。

不能对目录创建硬链接。

硬链接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬链接到重要文件,有防止“误删”的功能。

只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个链接被删除后,文件的数据块及目录的连接才会被释放,也就是说,文件才会被真正删除。

软链接和源文件是两个不同的文件,支持跨文件系统建立。

# 1.6.17 whereis

查命令、源文件和man文件。

locate the binary, source, and manual page files for a command。

-b 只搜索二进制。

# 1.6.18 mkdir

-p 嵌套创建子目录。

# 1.6.19 ps

列出当前进程。

-l 查看当前终端的进程

-ef 以标准语法查看进程。

-aux 使用 BSD 语法查看进程。

-le

-axj 查看所有守护进程

-efj 查看所有守护进程

其中:

  • USER 进程的启动者
  • PID 进程 ID
  • %CPU CPU 占用百分比
  • %MEM 内存占用百分比
  • VSZ 占用虚拟内存(swap空间)的大小
  • RSS 占用常驻内存(物理内存)的大小
  • TTY teel to you,终端,? 表示不需要终端或未知终端
  • STAT 进程状态:
    • D 无法中断的休眠状态
    • S 休眠 sleep
    • R 运行
    • Z zombie ,僵死
    • < 高优先级
    • N 低优先级
    • s 父进程
    • + 前台进程
    • X 死掉的进程
    • L 有些页被缩进内存
    • l 多线程,克隆线程。
    • T 停止或被追踪。
  • START 启动改进程的时间
  • TIME 该进程占用 CPU 时间
  • COMMAND 启动该进程的命令的名称

ps aux --sort=-%mem | head -n 10 查找内存占用率最高的几个应用。

# 1.6.20 kill

kill [-signal] PID

给指定进程发送指定信号. 如果没有指定信号, 则发送 TERM信号. TERM 信号会杀死不能俘获该信号的进程. 对于其他进程,可能需要使用 KILL (9) 信号, 因为该信号不能够被俘获.

SIGHUP 1 终端在结束时,会给其下所有进程发送某个信号。对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。

SIGINT 2 结束进程 C-C

SIGQUIT 3 结束进程 C-\

6 主动让进程 abort、coredump,gdb 后可以查看原因。

SIGUSR1 10 自定义

SIGUSR2 12 自定义

SIGKILL 9 杀死进程信号,不能不捕捉,不能被忽略、阻塞、注册。

SIGALRM 14 闹钟信号,定时器,当倒计时进程结束,结束进程

SIGTERM 15 终止信号。

SIGHLD 17 子进程结束,给父进程发送的信号

SIGSTOP 19 暂停进程,不能被捕捉信号,不能被忽略,不能被阻塞。

SIGTSTP 20 暂停进程,C-Z

# 1.6.21 chown

修改文件所有者和组别。

# 1.6.22 sync

将内存的数据写回硬盘,并释放缓存。 Linux系统运行过程中,会有大量的临时数据驻留在内存缓存区,在关闭系统时需要将内存数据与硬盘数据进行同步校验,以保证系统数据不丢失。因此,通常sync命令是在关闭Linux系统前时使用。

# 1.6.23 adduser

添加用户。

deluser 删除用户的同时删除用户的工作目录。

delgroup 删除用户组。

/etc/shadow文件是加密的用户清单。

/etc/passwd文件是系统能够识别的用户清单。

/etc/group 文件包含了UNIX组的名称和每个组中成员列表。

# 1.6.24 locate

超快速查找任意文件。

查找速度最快,但需要更新数据库。

$ sudo updatedb

-r 使用正则表达式,如 locate -r '\bls$'

# 1.6.25 find

功能最强大,但速度慢。

find [path] [expression]
1

path 是要查找的目录路径,可以是一个目录或文件名,也可以是多个路径,多个路径之间用空格分隔,如果未指定路径,则默认为当前目录。

expression 是可选参数,用于指定查找的条件,可以是文件名、文件类型、文件大小等等。

常用 expression:

  • -name pattern:按文件名查找,支持使用通配符 * 和 ?。
  • -type type:按文件类型查找,可以是 f(普通文件)、d(目录)、l(符号链接)等。
  • -size [+-]size[cwbkMG]:按文件大小查找,支持使用 + 或 - 表示大于或小于指定大小,单位可以是 c(字节)、w(字数)、b(块数)、k(KB)、M(MB)或 G(GB)。
  • -mtime days:按修改时间查找,支持使用 + 或 - 表示在指定天数前或后,days 是一个整数表示天数。
  • -user username:按文件所有者查找。
  • -group groupname:按文件所属组查找。

实例:

# 查找当前目录下名为 file.txt 的文件:
find . -name file.txt
# 将当前目录及其子目录下所有文件后缀为 .c 的文件列出来:
find . -name "*.c"
# 将当前目录及其子目录中的所有文件列出:
find . -type f
# 查找 /home 目录下大于 1MB 的文件:
find /home -size +1M
# 查找 /var/log 目录下在 7 天前修改过的文件:
find /var/log -mtime +7
# 将当前目录及其子目录下所有最近 20 天前更新过的文件列出,不多不少正好 20 天前的:
find . -ctime  20
# 将当前目录及其子目录下所有 20 天前及更早更新过的文件列出:
find . -ctime  +20
# 将当前目录及其子目录下所有最近 20 天内更新过的文件列出:
find . -ctime  20
# 查找 /var/log 目录中更改时间在 7 日以前的普通文件,并在删除之前询问它们:
find /var/log -type f -mtime +7 -ok rm {} \;
# 查找当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件:
find . -type f -perm 644 -exec ls -l {} \;
# 查找系统中所有文件长度为 0 的普通文件,并列出它们的完整路径:
find / -type f -size 0 -exec ls -l {} \;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 1.6.26 grep

打印匹配给定模式的行。

grep [options] PATTERN [FILE]

grep enum /usr/include/*

# 1.6.27 size

指定输入文件各段及其总和的大小。(可执行文件、静态库、动态库、目标文件)

# 1.6.28 strace

跟踪可执行程序的系统调用。

strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通 过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。

每一行都是一条系统调用,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。

strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核。

# 1.6.29 nm

nm 是name 的缩写,它显示指定文件中的符号信息,文件可以是对象文件、可执行文件或对象文件库。如果文件中没有包含符号信息,nm报告该情况,单不把他解释为出错。nm缺省情况下报告十进制符号表示法下的数字值。

nm -C xxx.o

# 1.6.30 umask

Linux 不同,它是通过使用 umask 默认权限来给所有新建的文件和目录赋予初始权限的。

root用户默认是0022,普通用户默认是 0002

文件(或目录)的初始权限 = 文件(或目录)的最大默认权限 - umask权限

umask -S 查看默认权限

默认权限:文件 0777 - 0002 = 0755 目录 0666 - 0002 = 0644

# 1.6.31 ldd

命令可以查看一个可执行程序依赖的共享库。

# 1.6.32 fg,bg,jobs

jobs -l 命令可以用来查看当前终端放入后台的工作

fg %num 命令用于把后台工作恢复到前台执行

bg %num 把后台暂停的工作恢复到后台执行

# 1.6.33 nohub,&

nohup 不挂断地运行命令。no hangup的缩写,意即“不挂断”。命令的作用就是让后台工作在离开操作终端时,也能够正确地在后台执行。

nohup 命令运行由 Command参数和任何相关的 Arg参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。 如果不将 nohup 命令的输出重定向,输出将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。

nohup COMMAND & 这样就能使命令永久的在后台执行。

# 1.6.34 netstat

netstat -tunlp 用于显示 tcp,udp 的端口和进程等相关情况。

netstat 查看端口占用语法格式:

netstat -tunlp | grep 端口号

  • -t (tcp) 仅显示tcp相关选项
  • -u (udp)仅显示udp相关选项
  • -n 拒绝显示别名,能显示数字的全部转化为数字
  • -l 仅列出在Listen(监听)的服务状态
  • -p 显示建立相关链接的程序名

例如查看 8000 端口的情况,使用以下命令:

netstat -tunlp | grep 8000

tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 26993/nodejs

更多命令:

netstat -ntlp //查看当前所有tcp端口

netstat -ntulp | grep 80 //查看所有80端口使用情况

netstat -ntulp | grep 3306 //查看所有3306端口使用情况

# 1.6.35 uname

uname -a

uname -r 查看 kernel 版本。

# 1.6.36 hexdump

二进制文件查看工具,它可以将二进制文件转换为ASCII、八进制、十进制、十六进制格式进行查看。

-C 每个字节显示为 16 进制和相应的 ASCII 字符。

-c 每个字节显示为 ascii 字符。

-x 双字节 16 进制显示。

-d 两个字节显示为 10 进制。

-b 每个字节显示为 8 进制。

-o 两个字节显示为 8 进制。

# 1.6.37 diff

Linux diff 命令用于比较文件的差异。

diff 以逐行的方式,比较文本文件的异同处。如果指定要比较目录,则 diff 会比较目录中相同文件名的文件,但不会比较其中子目录。

  • -c 显示全部内文,并标出不同之处。
  • -r 比较子目录中的文件。
  • -b 忽略空格.
  • -B 忽略空行
  • -u 合并输出
  • -y 对比结果并排输出

带 < 的部分表示左边文件内容, 中间的 - - - 则是两个文件内容的分隔符号, 带 > 的部分表示右边文件内容。

[root@ shell_practice]# cat file
> linux
> haha
> redhat
> centos
> EOF
[root@ shell_practice]# cat file1
> linux ubuntu
> redhat
> EOF
[root@ shell_practice]#

# " 1,2c1 " , 第一个文件 (file) 的第 1,2 行,做出修改才能与第二个文件 (file1) 第 1 行相匹配。
# " 4d2 " , 第一个文件 (file) 的第 4 行 删除才能与第二个文件 (file1) 第 2 行相匹配。
[root@ shell_practice]# diff file file1
1,2c1
< linux
< haha
---
> linux ubuntu
4d2
< centos
[root@ shell_practice]#
>linux


[root@ shell_practice]# diff file file1 -y
linux                                    | linux ubuntu
haha                                     <
redhat                                     redhat
centos                                   <
[root@ shell_practice]#


[root@ shell_practice]# diff file1 file -y
linux ubuntu                             | linux
                                         > haha
redhat                                     redhat
                                         > centos
[root@ shell_practice]#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 1.6.38 type

type 命令,type命令 用来显示指定命令的类型,判断给出的指令是内部指令还是外部指令。

type ls

命令类型:

  • alias:别名。
  • keyword:关键字,Shell保留字。
  • function:函数,Shell函数。
  • builtin:内建命令,Shell内建命令。
  • file:文件,磁盘文件,外部命令。
  • unfound:没有找到。

# 1.6.39 xargs

xargs和管道类似,都是把第一个命令的输出传递到第二个命令。

与管道不同的是,管道给第二个命令传递是直接传到命令输入上,这种方式要求命令本身的支持,支持的命令较少。

而xargs,则是把第一个命令的输出作为参数传递到第二个命令上,这种方式只要第二个命令可以接受参数即可,支持的命令较多。

➜  ~ echo test.txt | cat
test.txt
➜  ~ echo test.txt | xargs cat
content of test.txt
# echo test.txt | cat 是把 "test.txt" 这个字符串直接让cat输出
# echo test.txt | xargs cat 是把 "test.txt" 作为参数传递给cat,表示把 test.txt 这个文件的内容输出
1
2
3
4
5
6

# 1.6.40 -exec

find . -name "test.txt" -exec cat {} \;

content of test.txt
1
2
3

-exec与xargs不同的是:

-exec是将结果逐条传递给后面的命令,后面的命令逐条执行。 xargs是将结果作为一个列表全部传递给后面的命令,后面的命令一次性执行参数串,可以通过xargs -p ls -l来查看即将要执行的完整的命令。

find . -name 'core' -type f -exec rm {}
find . -name 'core' -type f -print | xargs rm
1
2

# 1.7 ELF 文件

ELF文件是一种用于二进制文件、可执行文件、目标代码、共享库和core转存格式文件。是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。

elf 文件头,内部分段

有三类文件属于 ELF 格式,

  1. 可执行文件
  2. 目标文件。

readelf -a 查看 elf 文件。

1)可重定位文件(Relocatable File)

包含适合于与其他目标文件链接来创建可执行文件或者共享目标文件的代码和数据,即 xxx.o 文件。

2)可执行文件(Executable File)

包含适合于执行的一个程序,此文件规定了 exec() 如何创建一个程序的进程映像,即 a.out文件。

3)共享目标文件(Shared Object File)

包含可在两种上下文中链接的代码和数据。首先链接编辑器可以将它和其它可重定位文件和共享目标文件一起处理,生成另外一个目标文件。其次,动态链接器(Dynamic Linker)可能将它与某个可执行文件以及其它共享目标一起组合,创建进程映像,即 xxx.so文件。

4)内核转储(core dumps)

存放当前进程的执行上下文,用于dump信号触发。

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。

objdump -D 查看反汇编信息。

objdump -S 查看目标的汇编代码。

objdump -d file 反汇编

objdemp -j .txt -S file 反汇编并显示 text段即代码段内容,尽可能以源码形式表示

# 1.8 常见服务

/etc/init.d/ssh restart 重启 ssh 服务。

service sshd restart

systemctl status tftpd-hpa 查看服务状态。

service tftpd-hpa status

sshd 服务,远程访问虚拟机服务。

Samba 服务,linux 和 windows 共享目录

tftp 服务,提供内核镜像 zImage 供 uboot 下载。

nfs 服务,提供网络文件系统。

# 1.9 内核空间

# 1.10 文件类型

文件类型	文件特点
普通文件	标识符 ‘-’ ,用open方式创建
目录文件	标识符 ‘d’ ,用mkdir方式创建
链接文件	标识符 ‘l’, ln -s 创建, 又可以分为软链接,硬链接
管道文件	标识   ‘p’, 用mkfifo创建
socket文件	标识符 ‘s’
字符设备文件	标识符 ‘c’
块设备文件	标识符 ‘b’
1
2
3
4
5
6
7
8

有名管道文件、字符设备文件、块设备文件、套接字(socket)文件不占磁盘空间。

# 杂项

  • 当解析路径时,Linux会将连续的斜杠视为一个单独的分隔符,而不会将其视为多个分隔符。这是因为Linux将多个连续的斜杠视为一个斜杠,以避免路径中的重复斜杠引起的混淆。
最后更新: 2023/11/7 08:36:05