1. shell
shell
是Linux
系统中运行的一种特殊程序。在用户和内核之间之间充当“翻译官”,用户登陆Linux
系统时,自动加载一个Shell
程序,Bash
是Linux
系统中默认使用的Shell
程序。
- 内核:用于调用计算机硬件资源
- shell:将用户指令转换成计算机语言让内核去调用计算机硬件资源
2. Bash解析器常用快捷键(Teminal)
bash
是一个文件,linux系统中万物皆文件,bash
文件位于/bin/bash
,bash
使用的快捷键:
Tab
键:补齐命令,补齐路径,显示当前目录下的所有目录- 使用快捷键
Ctrl + L
清除终端上的显示(类似于DOS的cls清屏功能),也可用clear
指令 ctlr+c
的作用是中断终端的操作。- 遍历输入的历史命令:从当前位置向上遍历
ctrl + p
或↑
;从当前位置向下遍历ctrl + n(↓)
- 光标相关操作
- 光标左移:
ctrl + b (←)
- 坐标右移:
ctrl + f (→)
- 移动到头部:
ctrl + a(Home)
- 移动到尾部:
ctlr + e(End)
- 字符删除
- 删除光标前边的字符:ctrl + h(Backspace)
- 删除光标后边的字符:ctrl + d
- 删除光标前所有内容:ctrl + u
- 删除光标后所有内容:ctrl + k
3. 系统目录
/
:根目录,一般根目录下只存放目录,在Linux
下有且只有一个根目录。所有的东西都是从这里开始。当你在终端里输入/home
,你其实是在告诉电脑,先从/(根目录)开始,再进入到home目录。/bin
: 这一目录中存放了供超级用户和一般用户都可以使用的命令,常用的命令ls、tar、mv、cat
等/usr/bin
: 安装的外部的命令,usr
表示的是unix software source
,不是user。/boot
:放置linux
系统启动时用到的一些文件,如Linux
的内核文件/boot/vmlinuz
,系统引导管理器/boot/grub
。/dev
:存放linux
系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,/etc
:系统配置文件存放的目录,不建议在此目录下存放可执行文件,重要的配置文件有/etc/inittab、/etc/fstab、/etc/init.d、/etc/X11、/etc/sysconfig、/etc/xinetd.d。
/home
:系统默认的用户家目录,新增用户账号时,用户的家目录都存放在此目录下,~表示当前用户的家目录,~edu
表示用户edu
的家目录。/lib
:内核级别,系统使用的函数库的目录,包含许多被/bin/
和/sbin/
中的程序使用的库文件。/usr/lib
: 系统级别,目标库文件,包括动态连接库加上一些通常不是直接调用的可执行文件的存放位置。这个目录功能类似/lib目录/usr/local/lib
:用户级别,包含许多被/bin/
和/sbin/
中的程序使用的库文件。/usr/include
:C程序语言编译使用的头文件。linux
下开发和编译应用程序所需要的头文件一般都存放在这里,通过头文件来使用某些库函数/lost+fount
:系统异常产生错误时,会将一些遗失的片段放置于此目录下。/mnt、/media
:光盘默认挂载点,通常光盘挂载/mnt/cdrom
下,也不一定,可以选择任意位置进行挂载。/opt
:给主机额外安装软件所摆放的目录。/proc
:此目录的数据都在内存中,如系统核心,外部设备,网络状态,由于数据都存放于内存中,所以不占用磁盘空间,比较重要的目录有/proc/cpuinfo、/proc/interrupts、/proc/dma、/proc/ioports、/proc/net/*
等。/root
:系统管理员root的家目录。/sbin、/usr/sbin、/usr/local/sbin
:放置系统管理员使用的可执行命令,如fdisk、shutdown、mount
等。与/bin
不同的是,这几个目录是给系统管理员root使用的命令,一般用户只能"查看"而不能设置和使用。/tmp
:一般用户或正在执行的程序临时存放文件的目录,任何人都可以访问,重要数据不可放置在此目录下。/srv
:服务启动之后需要访问的数据目录,如www
服务需要访问的网页数据存放在/srv/www
内。/usr
:应用程序存放目录,/usr/bin
存放应用程序,/usr/share
存放共享数据,/usr/lib
存放不能直接运行的,却是许多程序运行所必需的一些函数库文件。/usr/local
:存放软件升级包。/usr/share/doc:
系统说明文件存放目录。/usr/share/man:
程序说明文件存放目录。/var
:放置系统执行过程中经常变化的文件,如随时更改的日志文件/var/log,/var/log/message
所有的登录文件存放目录,/var/spool/mail
邮件存放的目录,/var/run
程序或服务启动后,其PID存放在该目录
4. Linux的文件
在Linux世界里,一切皆文件。在Linux中,文件可分为以下几种:普通文件(普通文件、可执行文件、压缩文件)、目录文件、设备文件、链接文件和套接字
文件符号标识:
- 普通文件:
-
- 目录:
d
- 字符设备:
c
- 管道:
p
- 符号链接:
l
- 套接字:
s
- 符号连结:
l
- 一般文件:
f
5. Linux常用命令
Linux的命令分为内建命令和外部命令。shell
内建命令是指bash
工具中集成的命令,一般有一些都会有一个与之同名的系统函数。外部命令是安装外部软件所带的命令。
5.1 内建命令和外部命令的区别
内部命令:实际上是
shell
程序的一部分,其中包含的是一些比较简单的linux
系统命令,这些命令由shell
程序识别并在shell
程序内部完成运行,通常在linux
系统加载运行shell
时就被加载并驻留在系统内存中。内部命令是写在bashy源码里面的,其执行速度比外部命令快,因为解析内部命令shell不需要创建子进程。exit,history,cd,echo
等就是内建命令1
help 内建命令
外部命令:外部命令是
linux
系统中的实用程序部分,因为实用程序的功能通常都比较强大,所以其包含的程序量也会很大,在系统加载时并不随系统一起被加载到内存中,而是在需要时才将其调用内存。通常外部命令的实体并不包含在shell
中,但是其命令执行过程是由shell
程序控制的。shell
程序管理外部命令执行的路径查找、加载存放,并控制命令的执行。外部命令是在bash
之外额外安装的,通常放在/bin,/sbin,/usr/bin,/usr/sbin,/usr/local/sbin
等等。可通过echo $PATH
命令查看外部命令的存储路径1
2//这是外部命令一个--help选项,不是help指令
外部命令 --helptype
命令可以分辨内部命令与外部命令1
2
3
4//常用的三个参数:-t对应-type,-a对应-all,-p对应-path,
type [-a | -t | -p] name
//或
type [-all | -type | -path] name
5.2 内建命令使用
所有内建命令如下:加星号的为常用项
命令 | 说明 | 重要程度 |
---|---|---|
: |
扩展参数列表,执行重定向操作 | |
. |
读取并执行指定文件中的命令(在当前shell环境中) | |
alias |
为指定命令定义一个别名 | |
bg |
将作业以后台模式运行 | |
bind |
将键盘序列绑定到一个readline 函数或宏 |
|
break |
退出for、while、selec t或until 循环 |
|
builtin |
执行指定的shell 内建命令 |
|
caller |
返回活动子函数调用的上下文 | |
cd |
将当前目录切换为指定目录 | * |
command |
执行指定的命令,无需进行通常的shell查找 | |
compgen |
为指定单词生成可能的补全匹配 | |
complete |
显示指定的单词是如何补全的 | |
compopt |
修改指定单词的补全选项 | |
continue |
继续执行for、while、select或until 循环的下一次迭代 |
|
declare |
声明一个变量或者变量类型 | |
dirs |
显示当前存储目录的列表 | * |
disown |
从进程作业表中删除指定的作业 | |
echo |
将指定字符串输出到STDOUT |
* |
enable |
启用或禁止指定的内建shell 命令 |
|
eval |
将指定的参数拼接成一个命令,然后执行该命令 | |
exec |
用指定命令替换shell 进程 |
|
exit |
强制shell 以指定的退出状态码退出 |
* |
export |
设置子shell 进程可用的变量 |
|
fc |
从历史记录中选择命令列表 | |
fg |
将作业以前台模式运行 | |
getopts |
分析指定的位置参数 | |
hash |
查找并记住指定命令的全路径名 | |
help |
显示帮助文件 | * |
history |
显示命令历史记录 | * |
jobs |
列出活动作业 | |
kill |
向指定的进程ID发送一个系统信号 | * |
let |
计算一个数学表达式中的每个参数 | |
local |
在函数中创建一个作用域受限的变量 | |
logout |
退出登录shell |
|
mapfile |
从STDIN 读取数据行,并将其加入索引数组 |
|
popd |
从目录栈中删除记录 | |
printf |
使用格式化字符串显示文本 | * |
pushd |
向目录栈添加一个目录 | |
pwd |
显示当前工作目录的路径名 | * |
read |
从STDIN 读取一行数据并将其赋值给一个变量 |
* |
readarray |
从STDIN 读取数据行并将其放入索引数组 |
|
readonly |
从STDIN 读取一行数据并将其赋值给一个不可修改的变量 |
|
return |
强制函数以某个值退出,这个值可以被调用脚本提取 | * |
set |
设置并显示环境变量的值和shell属性 | |
shift |
将位置参数依次向下降一个位置 | |
shopt |
打开/关闭控制shell 可选行为的变量值 |
|
source |
读取并执行指定文件中的命令(在当前shell 环境中) |
* |
suspend |
暂停shell 的执行,直到收到一个SIGCONT 信号 |
|
test |
基于指定条件返回退出状态码0或1 | |
times |
显示累计的用户和系统时间 | * |
trap |
如果收到了指定的系统信号,执行指定的命令 | |
type |
显示指定的单词如果作为命令将会如何被解释 | |
typeset |
声明一个变量或变量类型 | |
ulimit |
为系统用户设置指定的资源的上限 | * |
umask |
为新建的文件和目录设置默认权限 | * |
unalias |
删除指定的别名 | |
unset |
删除指定的环境变量或shell 属性 |
|
wait |
等待指定的进程完成,并返回退出状态码 |
5.2.1 cd命令
cd
命令是改变当前工作目录 1
2
3
4
5
6
7cd ../ 返回上一级目录
cd / 进入根目录
cd ~ 进入用户主目录
如:
trluper@trluper-virtual-machine:~$ cd ~
trluper@trluper-virtual-machine:~$ pwd
/home/trluper
5.2.2 dirs命令
dirs
命令用于显示Shell
目录中的堆栈记录。不加选项时显示当前的Shell命令堆栈中的所有目录,显示时左边为最新加入的目录。
选项 | 作用 |
---|---|
-c |
删除目录堆栈中的所有记录 |
-l |
以完整格式显示堆栈中的目录。显示用户宿主目录时,列出完整路径,而不是“~” |
-n |
显示右起第n个目录(n从0计数) |
+n |
显示左起第n个目录 (n从0计数) |
-p |
以每行一个记录的方式列出堆栈中多有记录 |
-v |
以每行一个记录的方式列出堆栈中所有记录,并在每行加上序号(从0开始编号) |
1 | trluper@trluper-virtual-machine:~/Documents$ dirs -v |
5.2.3 echo命令
echo
命令用于将输入的字符串送往标准输出,默认输出的字符间以空白字符隔开,并在最后加上换行号。常与重定向命令>
结合使用。 1
echo [OPTION]... [STRING]...
参数选项 | 描述 |
---|---|
-n |
不输出行尾的换行符,不自动换行 |
-e |
允许对下面列出的加反斜线转义的字符进行解释 |
-E |
默认选项,禁止对在STRINGs中的那些序列进行解释 |
1 | trluper@trluper-virtual-machine:~/Documents$ echo -e "这是echo" |
5.2.4 help命令
help命令用于显示shell
内部命令的帮助信息。help
命令只能显示shell
内部的命令帮助信息。而对于外部命令的帮助信息只能使用man
或者info
或者以外部命令的--help
选项查看。 1
2
3
4trluper@trluper-virtual-machine:~/Documents$ help cd
cd: cd [-L|[-P [-e]] [-@]] [dir]
Change the shell working directory.
.....
5.2.5 history命令
Bash
有完善的历史命令,这对于简化管理操作、排查系统错误都有重要的作用,而且使用简单方便,建议大家多使用历史命令。系统保存的历史命令可以使用history
命令查询。 1
history [选项] [历史命令保存文件]
选项 | 作用 |
---|---|
c |
清空历史命令 |
w |
把缓存中的历史命令写入历史命令保存文件中。如果不手工指定历史命令保存文件,则放入默认历史命令保存文件~/.bash_history 中 |
1 | trluper@trluper-virtual-machine:~/Documents$ history |
5.2.6 kill命令
kill
命令用于删除执行中的程序或工作。kill
可将指定的信息送至程序。预设的信息为SIGTERM(15)
,可将指定程序终止。若仍无法终止该程序,可使用SIGKILL(9)
信息尝试强制删除程序。程序或工作的编号可利用 ps
指令或jobs
指令查看。 1
kill [信号] PID
信号编号 | 信号名 | 含义 |
---|---|---|
0 | EXIT |
程序退出时收到该信息。 |
1 | HUP |
挂掉电话线或终端连接的挂起信号,这个信号也会造成某些进程在没有终止的情况下重新初始化。 |
2 | INT |
表示结束进程,但并不是强制性的,常用的Ctrl+C 组合键发出就是一个 kill -2 的信号。 |
3 | QUIT |
退出。 |
9 | KILL |
杀死进程,即强制结束进程。 |
11 | SEGV |
段错误。 |
15 | TERM |
正常结束进程,是kill 命令的默认信号。 |
5.2.7 pwd命令
命令用于显示工作目录。执行pwd
指令可立刻得知您目前所在的工作目录的绝对路径名称。 1
2trluper@trluper-virtual-machine:~/Documents$ pwd
/home/trluper/Documents
5.2.8 ulimit命令
ulimit
用来限制每个用户可使用的资源,如CPU、内存、句柄等。 1
2ulimit [-SHabcdefiklmnpqrstuvxPT] [limit] 设置limit
ulimit [-SHabcdefiklmnpqrstuvxPT] 查询
选项 | 功能 |
---|---|
S |
表示软限制,超出设定的值会告警 |
H |
表示硬限制,超出设定的值会报错 |
a |
列出系统所有资源限制的值 |
d |
每个进程数据段的最大值 |
f |
当前shell 可创建的最大文件容量 |
l |
可以锁定的物理内存的最大值 |
m |
可以使用的常驻内存的最大值 |
n |
每个进程可以同时打开的最大文件句柄数 |
p |
管道的最大值 |
s |
堆栈的最大值 |
t |
每个进程可以使用CPU的最大时间 |
u |
每个用户运行的最大进程并发数 |
v |
当前shell 可使用的最大虚拟内存 |
1 | trluper@trluper-virtual-machine:~/Documents$ ulimit -n |
5.2.9 source命令和.命令
.sh后缀的文件为Linux的脚本文件,里面可以写入许多执行命令语句。然后我们可以通过使用source
命令或者.
在当前shell环境来执行该脚本文件中的所有语句。
1 | source test.sh |
来看一下四个执行的区别: 1
2
3
4
5
6
7
8
9
10
11
12//test.sh文件:
#!/bin/bash
echo "step 1 sleeping"
sleep 200
echo "step 2 sleeping"
sleep 200
//执行:
./test.sh //当前shell下正常执行,这种执行方式需要test.sh的执行权限,开启两个进程一个是test.sh,一个是sleep
sh test.sh //开启新的shell执行,不用执行权限,有读取权限即可,开两个新进程:一个bash,一个sleep
. test.sh //当前shell下执行,只需要读取权限即可,开启一个新进程sleep
source test.sh //同第三个一样
5.3.10 umask命令
umask
命令用来设置限制新建文件权限的掩码。当新文件被创建时,其最初的权限由umask设置的掩码决定。用户每次注册进入系统时,umask
命令都被执行, 并自动设置掩码mode
来限制新文件的权限。用户可以通过再次执行umask
命令来改变默认值,新的权限将会把旧的覆盖掉。注意umask命令是指定哪些权限将在新文件的默认权限中被删除 1
2
3
4
5
6 umask [-p] [-S] [mode]
-p 以八进制数字表示掩码
-S 以符号格式表示掩码
ugo:u表示当前用户权限,g为组用户权限,o为其他用户权限
rwx:r为读权限(4),w为写权限(2),x为执行权限(1)
我们通过umask
查询其默认的删除权限代码:
1 | //当前目录的umask掩码 |
因为umask的掩码表示被删除的权限,则目录拥有的权限为777-002=765
,则以后建立的目录的权限为u=rwx,g=r-x,o=r-x
。如果想要改变默认,则设置umask
,那么以后新建的目录或文件会按这个来删除权限
1 | trluper@trluper-virtual-machine:~$ umask -p 555 //以后新建的目录和文件删除所有用户的读和执行权限 |
5.3 外部命令
5.3.1 sudo命令
sudo
命令以系统管理者的身份执行指令,也就是说,经由sudo
所执行的外部指令就好像是root
亲自执行。 1
2trluper@trluper-virtual-machine:~$ sudo --help
sudo - execute a command as another user
usage: sudo -h | -K | -k | -V
V
显示版本编号h
会显示版本编号及指令的使用方式说明l
显示出自己(执行sudo
的使用者)的权限k
将会强迫使用者在下一次执行sudo
时问密码(不论有没有超过 N 分钟)
1 | trluper@trluper-virtual-machine:~$ sudo cd / |
5.3.2 su命令
su
(英文全拼:switch user
)命令用于变更为其他使用者的身份,除root
外,需要键入该使用者的密码。使用权限:所有使用者。 1
2
3
4root@trluper-virtual-machine:~
trluper@trluper-virtual-machine:/root$ sudo su //切回root
[sudo] password for trluper:
root@trluper-virtual-machine:~#
5.3.3 ls命令
是英文单词list
的简写,其功能为列出目录的内容,是用户最常用的命令之一,它类似于DOS
下的dir
命令。
选项 | 作用 |
---|---|
-a |
显示所有文件及目录. 开头的隐藏文件也会列出) |
-l |
除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出 |
-r |
将文件以相反次序显示(原定依英文字母次序) |
-t |
将文件依建立时间之先后次序列出 |
-A |
同 -a ,但不列出 . (目前目录) 及.. (父目录) |
-F |
在列出的文件名称后加一符号;例如可执行档则加 * , 目录则加 / |
-R |
若目录下有文件,则以下之文件亦皆依序列出 |
1 | trluper@trluper-virtual-machine:~$ ls -l |
5.3.4 man命令
man命令是Linux下的帮助指令,通过man指令可以查看Linux中的指令帮助、配置文件帮助和编程帮助等信息:man [选项] 命令名
linux中各个分页的意义:
分页 | 内容 |
---|---|
1 |
Standard commands (标准命令) |
2 |
System calls 系统调用,如open,write |
3 |
Library functions 库函数,如printf,fopen |
4 |
Special devices (设备文件的说明,/dev下各种设备) |
5 |
File formats (文件格式,如passwd) |
6 |
Games and toys (游戏和娱乐) |
7 |
Miscellaneous (杂项、惯例与协定等,例如Linux档案系统、网络协定、ASCII 码;environ全局变量) |
8 |
Administrative Commands (管理员命令,如ifconfig) |
1 | trluper@trluper-virtual-machine:~$ man 3 open |
5.3.5 makdir命令
mkdir(英文全拼:make directory
)命令用于创建目录。需要注意的是新建目录的名称不能与当前目录中已有的目录或文件同名,并且目录创建者必须对当前目录具有写权限。参数-p
可递归创建目录。 1
2
3
4
5
6
7
8trluper@trluper-virtual-machine:~$ cd ./Documents/
trluper@trluper-virtual-machine:~/Documents$ ls
trluper@trluper-virtual-machine:~/Documents$ mkdir -p a/b
trluper@trluper-virtual-machine:~/Documents$ ls
a
trluper@trluper-virtual-machine:~/Documents$ mkdir mydir{1..3}
trluper@trluper-virtual-machine:~/Documents$ ls
a mydir1 mydir2 mydir3
5.3.6 rmdir命令
rmdir删除指定的目录,一个目录被删除之前必须是空的,'-p'递归删除目录 1
2
3
4
5trluper@trluper-virtual-machine:~/Documents$ ls
a mydir1 mydir2 mydir3
trluper@trluper-virtual-machine:~/Documents$ rmdir -p a/b/c
trluper@trluper-virtual-machine:~/Documents$ rmdir mydir{1..3}
trluper@trluper-virtual-machine:~/Documents$ ls
5.3.7 touch命令
touch
命令用于修改文件或者目录的时间属性,包括访问时间和修改时间,若文件不存在,系统会建立一个新的文件。即:
- 1)如果文件不存在, 创建新文件(只能是普通文件,不能是文件夹)
- 2)如果文件存在, 更新文件时间
1 | trluper@trluper-virtual-machine:~/Documents/mydir_1$ touch test.cpp |
5.3.8 cp命令
cp
命令的功能是将给出的文件或目录复制到另一个文件或目录中,即:
- 可以将一个或多个文件复制到另一个文件夹中
- 可以将目录即目录下的文件和子目录复制到另一个目录
- 可以将一个文件复制给另一个文件
选项 | 功能 |
---|---|
a |
此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于dpR参数组合 |
d |
复制时保留链接。这里所说的链接相当于Windows 系统中的快捷方式。 |
f |
覆盖已经存在的目标文件而不给出提示 |
i |
与 -f 选项相反,在覆盖目标文件之前给出提示,要求用户确认是否覆盖,回答y 时目标文件将被覆盖 |
p |
除复制文件的内容外,还把修改时间和访问权限也复制到新文件中 |
r |
若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件。 |
l |
不复制文件,只是生成硬链接文件,可以把硬链接当成源文件的副本,他和源文件一样的大小,但是事实上却不占任何空间 |
s |
不复制文件,创建文件的软链接,软链接就相当于windows的快捷键(即路径名) |
u |
当存在相同的文件时,只有源文件比目标文件新时,才会将源文件复制给目标文件 |
1.复制一个文件到另外一个文件夹 1
2
3
4
5cp 源文件 目标文件(夹):
trluper@trluper-virtual-machine:~/Documents/mydir_1$ cp test1.cpp /home/trluper/Documents/mydir_2
trluper@trluper-virtual-machine:~/Documents/mydir_1$ cd ../mydir_2
trluper@trluper-virtual-machine:~/Documents/mydir_2$ ls
test1.cpp
2. 复制多个文件到另外一个文件夹 1
2
3
4
5cp 源文件1 源文件2 目标文件夹 或cp 文件* 目标文件夹
trluper@trluper-virtual-machine:~/Documents/mydir_1$ cp -u *.cpp /home/trluper/Documents/mydir_2
trluper@trluper-virtual-machine:~/Documents/mydir_1$ cd ../mydir_2
trluper@trluper-virtual-machine:~/Documents/mydir_2$ ls
test1.cpp test2.cpp test3.cpp test.cpp
3. 复制目录到另一个目录
只需要记住复制文件夹一定要加-r
参数,否则会出现cp: omitting directory
错误。 1
2
3
4
5
6
7
8
9
10
11
12未加-r出错:
trluper@trluper-virtual-machine:~/Documents/mydir_1$ cp /home/trluper/Documents/mydir_1 /home/trluper/Documents/mydir_2
cp: -r not specified; omitting directory '/home/trluper/Documents/mydir_1'
加-r:
trluper@trluper-virtual-machine:~/Documents/mydir_1$ cp -r /home/trluper/Documents/mydir_1 /home/trluper/Documents/mydir_2
trluper@trluper-virtual-machine:~/Documents/mydir_1$ cd ../mydir_2
trluper@trluper-virtual-machine:~/Documents/mydir_2$ ls
mydir_1 test1.cpp test2.cpp test3.cpp test.cpp
trluper@trluper-virtual-machine:~/Documents/mydir_2$ cd mydir_1/
trluper@trluper-virtual-machine:~/Documents/mydir_2/mydir_1$ ls
mysondir test test1.cpp test2.cpp test3.cpp test.cpp
4. 复制文件到另一个文件
1 | 复制内容到文件 |
5. -u的重要性
1 | trluper@trluper-virtual-machine:~/Documents/mydir_2$ ls -l |
5.3.9 rm命令
可通过rm
删除文件或目录。使用rm
命令要小心,因为文件删除后不能恢复。为了防止文件误删,可以在rm
后使用-i
参数以逐个确认要删除的文件。
5.3.10 mv命令
用户可以使用mv
命令来移动文件或目录,也可以给文件或目录重命名。mv
与cp
时不同的,mv
是移动,cp
是复制一个。 1
mv [OPTION]... [-T] SOURCE DEST
选项 | 作用 |
---|---|
--backup |
若需覆盖文件,则覆盖前先行备份 |
-b |
当文件存在时,覆盖前,为其创建一个备份 |
-f |
若目标文件或目录与现有的文件或目录重复,则直接覆盖现有的文件或目录 |
-i |
交互式操作,覆盖前先行询问用户,如果源文件与目标文件或目标目录中的文件同名,则询问用户是否覆盖目标文件。用户输入y ,表示将覆盖目标文件 |
-S |
为备份文件指定后缀,而不使用默认的后缀 |
-u |
当源文件比目标文件新或者目标文件不存在时,才执行移动操作。 |
1 | trluper@trluper-virtual-machine:~/Documents/mydir_2$ mv ../mydir_1 . |
5.3.11 cat命令
cat:将文件内容一次性输出到终端。缺点是终端显示的内容有限,如果文件太长无法全部显示
-n
:对输出的所有行编号-b
:输出内容并且给非空行编号
1 | trluper@trluper-virtual-machine:~/Documents/mydir_2$ cat -n test.cpp |
5.3.12 less命令
less命令将文件内容分页显示到终端,可以自由上下浏览
5.3.13 head命令
head命令从文件头部开始查看前n行的内容。如果没有指定行数,默认显示前10行内容。 1
2head –n [行数] 文件名
head -n 30 /etc/passwd
5.3.14 find命令
find
命令功能非常强大也很复杂,通常用来在特定的目录下搜索符合条件的文件,也可以用来搜索特定用户属主的文件。 1
find path -option [ -print ] [ -exec -ok command ] {} \;
option
多达二十多种,这里列举两个:
- 按文件名查询,使用
-name
,如find . -name "test.cpp"
- 按文件类型查找,使用
-type
,如find . -type f
举例: 1
2
3
4
5
6
7
8//将当前目录及其子目录下所有最近 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 {} \;
5.3.15 grep命令
很多时候,我们并不需要列出文件的全部内容,而是从文件中找到包含指定信息的那些行,要实现这个目的,可以使用grep
命令。grep
命令是一个强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.其中pattern
为模式,它要么是字符串,要么是正则表达式,总而言之是我们检索的指定信息 1
grep [options] pattern filename
选项 | 功能 |
---|---|
-i |
不区分大小写 |
-c |
只输出匹配行的计数 |
-l |
查询多文件时只输出包含匹配字符的文件名 |
-n |
显示匹配行及行号 |
-s |
不显示不存在或无匹配文本的错误信息 |
-v |
显示不包含匹配文本的所有行,即反向查找 |
-o |
只显示匹配字符串的部分 |
-e |
实现多个选项的匹配,逻辑or 关系 |
-E |
使用扩展正则表达式,而不是基本正则表达式,在使用-E 选项时,相当于使用egrep |
正则表达式:
^
:此时匹配正则表达以“某字符串”开头的行$
:匹配正则表达式的以“某字符串”结尾的行[xyz]
:匹配方括号中的任意一个字符[^xyz]
:匹配除方括号中字符外的所有字符*
:匹配*
前面的字符,匹配0个或无数个[ - ]
: 范围匹配,如[A-C]
,即A、B、C
都符合要求
1. 查找以指定字字符串开头的行 1
2
3
4
5
6
7
8trluper@trluper-virtual-machine:~/Documents/mydir_2$ grep -in ^[a,q,r,f] hell.txt
2:QQWEWQE
5:FDSST
7:AFASRAY
12:ASDSAEE
13:FAFSDG
17:FBB
24:R
2. 查找以指定字结符串尾的行
1 | trluper@trluper-virtual-machine:~/Documents/mydir_2$ grep -in [a,q,r,f]$ hell.txt |
3.在文本中搜素只有一个字符的行,且为字母或数字
1 | trluper@trluper-virtual-machine:~/Documents/mydir_2$ grep -in ^[[:alnum:]]$ hell.txt |
4.匹配*
前面的字符,匹配0个或无数个
1 | trluper@trluper-virtual-machine:~/Documents/mydir_2$ grep -in "FDSS"* hell.txt |
5.3.16 |命令
管道|
一个命令的输出可以通过管道做为另一个命令的输入。即它只能处理经由前面一个指令传出的正确输出信息,对错误信息信息没有直接处理能力。然后,传递给下一个命令,作为标准的输入. 最常用的: 1
2
3
4
5
6
7
8
9
10ps -ef|gerp "进程名"
ps -aux|grep "进程名"
trluper@trluper-virtual-machine:~/Documents/mydir_2$ ps -ef|grep bash
trluper 2755 2754 0 16:03 pts/1 00:00:02 -bash
trluper 4549 4548 0 20:29 pts/0 00:00:00 -bash
trluper 4716 4549 0 20:49 pts/0 00:00:00 grep --color=auto bash
trluper@trluper-virtual-machine:~/Documents/mydir_2$ ps -aux|grep bash
trluper 2755 0.0 0.2 19972 5956 pts/1 Ss+ 16:03 0:02 -bash
trluper 4549 0.0 0.2 19864 5956 pts/0 Ss 20:29 0:00 -bash
trluper 4718 0.0 0.1 17864 2584 pts/0 S+ 20:49 0:00 grep --color=auto bas
5.3.17 ps命令
ps
(英文全拼:process status
)命令用于显示当前进程的状态,类似于windows
的任务管理器 1
ps [options]
ps
的参数非常多, 在此仅列出几个常用的参数并大略介绍含义
选项 | 作用 |
---|---|
a |
显示现行终端机下的所有程序,包括其他用户的程序 |
-a |
显示所有终端机下执行的程序,除了阶段作业领导者之外 |
-A |
显示所有程序 |
-e |
此选项的效果和指定”A”选项相同 |
-f |
显示UID,PPIP,C与STIME栏位 |
-u |
此选项的效果和指定”-U”选项相同 |
u |
以用户为主的格式来显示程序状况 |
-U |
列出属于该用户的程序的状况,也可使用用户名称来指定 |
U |
列出属于该用户的程序的状况 |
x |
显示所有程序,不以终端机来区分 |
1. -aux
输出格式
1 | trluper@trluper-virtual-machine:~/Documents/mydir_2$ ps -aux |
USER
: 行程拥有者PID: pid
%CPU
: 占用的CPU
使用率%MEM
: 占用的记忆体使用率VSZ
: 占用的虚拟记忆体大小RSS
: 占用的记忆体大小TTY
: 终端的次要装置号码 (minor device number of tty)STAT:
该行程的状态:D:
无法中断的休眠状态 (通常 IO 的进程)R:
正在执行中S:
睡眠状态,可被唤醒T:
暂停执行Z:
僵尸进程W:
没有足够的记忆体分页可分配s:
进程是会话首进程<:
高优先序的行程N:
低优先序的行程X:
死掉的进程START:
行程开始时间TIME:
执行的时间COMMAND:
所执行的指令
2. -ef
输出格式 1
2
3
4
5
6
7trluper@trluper-virtual-machine:~/Documents/mydir_2$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 13:20 ? 00:00:06 /sbin/init auto noprompt splash
root 2 0 0 13:20 ? 00:00:00 [kthreadd]
root 3 2 0 13:20 ? 00:00:00 [rcu_gp]
root 4 2 0 13:20 ? 00:00:00 [rcu_par_gp]
root 5 2 0 13:20 ? 00:00:00 [netns]
5.3.18 tar命令
tar
是Unix/Linux中最常用的备份工具,此命令可以把一系列文件归档到一个大文件中,也可以把档案文件解压以恢复数据。tar
这个命令并没有压缩的功能,它只是一个打包的命令,但是在tar
命令中增加一个选项-z
可以调用gzip
实现了一个压缩的功能,实行一个先打包后压缩的过程。当然你可以调用其他的压缩命令来压缩。tar
要指定扩展名 1
2
3
4
5
6//只打包
tar -cvf test.tar ./
//压缩当前文件内的所有内容打成和压缩成test.tar.gz包
tar -zcvf test.tar.gz ./
//解压缩和解包
tar -zxvf test.tar.gz
选项 | 作用 |
---|---|
-c |
创建一个新归档 |
-x |
从归档中解出文件 |
-f |
使用归档文件,一定为最后一个参数 |
-z |
通过 gzip 过滤归档 |
-t |
查看内容 |
-r |
向压缩归档文件末尾追加文件 |
-u |
更新原压缩包中的文件 |
-v |
显示所有过程 |
-f 是必须的,切记,这个参数是最后一个参数,后面只能接档案名。
linux中的压缩后缀:
*.gz
:由gzip
压缩,参数为-z
*.bz2
:由bzip2
压缩,参数为-j
*.Z
:由compress
压缩,参数为-Z
*.rar:
由rar
压缩,linux需下载rar
*.zip
:由zip
压缩,linux需下载zip
1 | trluper@trluper-virtual-machine:~/Documents$ tar -zcvf mytar.tar.gz ./ |
5.3.19 gzip命令
其实上面的tar
加-z
参数就已经完成了gzip
命令的工作了。tar
与gzip
命令结合使用实现文件打包、压缩。gzip
要指定扩展名
-d
:解压-r
:压缩所有子目录
1 | trluper@trluper-virtual-machine:~/Documents$ tar -cvf mytar1.tar mydir_2 |
5.3.20 zip和unzip命令
通过zip压缩文件的目标文件不需要指定扩展名,默认扩展名为zip。 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17压缩文件:zip -r 目标文件(没有扩展名) 源文件
解压文件:unzip -d 解压后目录文件 压缩文件
trluper@trluper-virtual-machine:~/Documents$ zip -r myzip mydir_2
adding: mydir_2/ (stored 0%)
adding: mydir_2/test.cpp (stored 0%)
adding: mydir_2/hell.txt (deflated 20%)
adding: mydir_2/mydir_1/ (stored 0%)
adding: mydir_2/mydir_1/test.cpp (stored 0%)
adding: mydir_2/mydir_1/test1.cpp (stored 0%)
adding: mydir_2/mydir_1/sondir/ (stored 0%)
adding: mydir_2/mydir_1/mysondir/ (stored 0%)
adding: mydir_2/mydir_1/test3.cpp (stored 0%)
adding: mydir_2/mydir_1/test (deflated 79%)
adding: mydir_2/mydir_1/test2.cpp (stored 0%)
adding: mydir_2/test (deflated 79%)
trluper@trluper-virtual-machine:~/Documents$ ls
mydir_2 mymdir_2 mytar1.tar.gz mytar.tar.gz myzip.zip
5.3.21 chmod命令
chmod
(英文全拼:change mode)命令是控制用户对文件的权限的命令。Linux/Unix 的文件调用权限分为三级 : 文件所有者Owner
、用户组Group
、其它用户ther Users
。在内建命令中我们通过设置umask
命令来指定新建的文件的权限,但是对于已经存在的文件的权限我们要怎么去修改呢,只能使用chmod
命令来修改 chmod
修改文件权限有两种使用格式字母法与数字法。 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//字母
trluper@trluper-virtual-machine:~/Documents$ ls -l
total 4
drwxrwxr-x 3 trluper trluper 4096 7月 16 20:39 mydir_2
-rw-rw-r-- 1 trluper trluper 0 7月 16 15:12 mymdir_2
trluper@trluper-virtual-machine:~/Documents$ chmod o+w mydir_2/
trluper@trluper-virtual-machine:~/Documents$ ls -l
total 4
drwxrwxrwx 3 trluper trluper 4096 7月 16 20:39 mydir_2
-rw-rw-r-- 1 trluper trluper 0 7月 16 15:12 mymdir_2
//数字
trluper@trluper-virtual-machine:~/Documents$ chmod 775 mydir_2/
trluper@trluper-virtual-machine:~/Documents$ ls -l
total 4
drwxrwxr-x 3 trluper trluper 4096 7月 16 20:39 mydir_2
-rw-rw-r-- 1 trluper trluper 0 7月 16 15:12 mymdir_2
5.3.22 >命令
>
命令是重定向命令。我们在bash上运行命令,其默认输出为当前的bash终端。当我们想要看查询的东西时(如ls命令),把原来输出到终端的,可以重定向到一个文件。命令后接 >文件名
,>
会覆盖,>>
不覆盖原来内容 1
2
3
4
5
6
7
8trluper@trluper-virtual-machine:~/Documents$ ls -l >text.txt
trluper@trluper-virtual-machine:~/Documents$ ls
mydir_2 mymdir_2 text.txt
trluper@trluper-virtual-machine:~/Documents$ cat text.txt
total 4
drwxrwxr-x 3 trluper trluper 4096 7月 16 20:39 mydir_2
-rw-rw-r-- 1 trluper trluper 0 7月 16 15:12 mymdir_2
-rw-rw-r-- 1 trluper trluper 0 7月 17 11:04 text.txt
5.3.23 ln命令
ln
命令是linux系统中一个非常重要命令,英文全称是“link”,即链接的意思,它的功能是为某一个文件在另外一个位置建立一个同步的链接。 一种是hard link
,又称为硬链接;另一种是symbolic link
,又称为符号链接。通俗一点理解,可以把硬链接当成源文件的副本,他和源文件一样的大小,但是事实上却不占任何空间。符号链接可以理解为类似windows一样的快捷方式。 符号链接 :
- 1.符号链接以路径的形式存在,类似于Windows操作系统中的快捷方式。
- 2.符号链接可以跨文件系统 ,硬链接不可以。
- 3.符号链接可以对一个不存在的文件名进行链接,硬链接不可以。
- 4.符号链接可以对目录进行链接,硬链接不可以。
硬链接:
- 1.硬链接以文件副本的形式存在,但不占用实际空间。
- 2.硬链接不允许给目录创建硬链接。
- 3.硬链接只有在同一个文件系统中才能创建。
1 | ln [参数] [源文件或目录] [目标文件或目录] |
常用参数:
选项 | 作用 |
---|---|
-b |
为每个已存在的目标文件创建备份文件 |
-d |
此选项允许“root”用户建立目录的硬链接 |
-f |
强制创建链接,即使目标文件已经存在 |
-n |
把指向目录的符号链接视为一个普通文件 |
-i |
交互模式,若目标文件已经存在,则提示用户确认进行覆盖 |
-s |
对源文件建立符号链接,而非硬链接 |
-v |
详细信息模式,输出指令的详细执行过程 |
1 | //软连接 |
5.3.24 file命令
file命令用于辨识文件类型。通过file
指令,我们得以辨识该文件的类型。 1
file [-bcLvz][-f <名称文件>][-m <魔法数字文件>...][文件或目录...]
选项 | 作用 |
---|---|
-b |
列出辨识结果时,不显示文件名称。 |
-c |
详细显示指令执行过程,便于排错或分析程序执行的情形。 |
-f<名称文件> |
指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称。 |
-L |
直接显示符号连接所指向的文件的类别。 |
-m<魔法数字文件> |
指定魔法数字文件。 |
-v |
显示版本信息。 |
-z |
尝试去解读压缩文件的内容。 |
[文件或目录...] |
要确定类型的文件列表,多个文件之间使用空格分开,可以使用shell通配符匹配多个文件。 |
1 | trluper@trluper-virtual-machine:~/Documents/ln_file$ file lntest1 |
5.3.25 chgrp命令/chown命令
chgrp
命令用来改变文件或目录所属的用户组。该命令用来改变指定文件所属的用户组。其中,组名可以是用户组的id
,也可以是用户组的组名。文件名可以是由空格分开的要改变属组的文件列表,也可以是由通配符描述的文件集合。如果用户不是该文件的文件主或超级用户(root),则不能改变该文件的组。同时必须在/etc/group
有该组名。 1
chgrp [选项] 组名 文件...
选项 | 作用 |
---|---|
-c |
效果类似-v 参数,但仅会显示更改的部分 |
-f |
不显示错误信息 |
-h |
只对符号连接的文件作修改,而不是该其他任何相关文件 |
-R |
递归处理,将指令目录下的所有文件及子目录一并处理 |
-v |
显示指令执行过程; |
1 | trluper@trluper-virtual-machine:~/Documents/ln_file$ cat /etc/group |
5.3.26 top命令
top
命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况 1
top [参数]
选项 | 作用 |
---|---|
-b |
批处理 |
-c |
显示完整的治命令 |
-I |
忽略失效过程 |
-s |
保密模式 |
-S |
累积模式 |
-i<时间> |
设置间隔时间 |
-u<用户名> |
指定用户名 |
-p<进程号> |
指定进程 |
-n<次数> |
循环显示的次数 |
1 | trluper@trluper-virtual-machine:~/Documents/ln_file$ top -p2567 |
5.3.27 ar命令
ar
命令用于建立或修改备存文件,或是从备存文件中抽取文件。可集合许多文件,成为单一的备存文件。在备存文件中,所有成员文件皆保有原来的属性与权限 1
ar [参数]
选项 | 作用 |
---|---|
-d |
删除备存文件中的成员文件 |
-m |
变更成员文件在备存文件中的次序 |
-p |
显示备存文件中的成员文件内容 |
-q |
将文件附加在备存文件末端 |
-r |
将文件插入备存文件中 |
-t |
显示备存文件中所包含的文件 |
-x |
自备存文件中取出成员文件 |
-c |
创建 |
-s |
建立索引 |
5.3.28 nm命令
nm
是names
的缩写,nm
命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等)。 一般来说,搞linux开发的人,才会用到nm
命令,非开发的人,应该用不到. 1
nm [参数]
5.3.29 查看端口使用
有时候我们需要知道某些应用使用的端口号,避免端口冲突,可使用下述命令 1. netstat
1
2
3netstat -anp
#通过与|和grep结合使用,可以查找任一个应用的端口使用情况
netstat -anp | grep redislsof
1
2#这个命令可以列出正在使用指定端口号的进程和它们的详细信息。
lsof -i :6379
6. vim编辑器
vi (Visual interface)
编辑器是Linux
系统中最常用的文本编辑器,vi
工作在字符模式下,不需要图形界面,非常适合远程及嵌入式工作,是效率很高的文本编辑器。vim
是vi
的升级版,它不仅兼容vi
的所有指令,而且还有一些新的特性,例如vim
可以撤消无限次、支持关键词自动完成、可以用不同的颜色来高亮你的代码。vim
普遍被推崇为类vi
编辑器中最好的一个。
6.1 vim的三种模式
vi有三种基本工作模式: 命令模式、文本输入模式(编辑模式)、末行模式
命令模式: 任何时候,不管用户处于何种模式,只要按一下
ESC
键,即可使vi
进入命令模式。我们在shell
环境(提示符为$
)下输入启动vim
命令,进入编辑器时,也是处于该模式下。在命令模式下,用户可以输入各种合法的vi
命令,用于管理自己的文档。此时从键盘上输入的任何字符都被当做编辑命令来解释,若输入的字符是合法的vi
命令,则vi
在接受用户命令之后完成相应的动作。但需注意的是,所输入的命令并不在屏幕上显示出来。若输入的字符不是vi
的合法命令,vi
会响铃报警。文本输入模式: 在命令模式下输入插入命令
i(I)、附加命令a(A) 、打开命令o(O)、替换命s(S)
都可以进入文本输入模式,此时vi窗口的最后一行会显示“插入”,可进行文本编辑.末行模式: 末行模式下,用户可以对文件进行一些附加处理。尽管命令模式下的命令可以完成很多功能,但要执行一些如字符串查找、替换、显示行号等操作还是必须要进入末行模式的。在命令模式下,输入冒号
:
即可进入末行模式。此时vi窗口的状态行会显示出冒号,等待用户输入命令。用户输入完成后,按回车执行,之后vi
编辑器又自动返回到命令模式下
6.2 命令模式下的命令操作
6.2.1 切换到编辑模式
6.2.2 光标移动
6.2.3 删除
常用:D
、dG
、nx
(n为数字)、ndd
6.2.4 查找
6.2.5 可视模式
6.2.6 粘贴和复制
p
:粘贴在光标后面P
:粘贴在光标前面y
:拷贝行Y
:拷贝行
6.3 末行模式下的命令操作
6.3.1 保存退出
6.3.2 替换
可以从上图总结:s(
代表本行,g
为所有(global)都替换,%
指本文件所有行,c
每次替换都要求确认
6.3.3 分屏
6.3.4 其他用法扩展
6.4 vim的配置文件所在
局部配置文件(推荐):~/.vimrc
全局配置文件:/etc/vim/vimrc
7. GCC和gcc++编译器
7.1 gcc和 GCC是两个不同的东西
GCC:GNU Compiler Collection
(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada
等语言。- 因此
gcc
是GCC
中的GUN C Compiler
(C 编译器);g++
是GCC
中的GUN C++ Compiler
(C++
编译器)。二者都可以编译c
或cpp
文件。只不过用gcc
编译c++
需要手动添加链接库 - 在编译阶段,
g++
会调用gcc
,对于c++
代码,两者是等价的,但是因为gcc
命令不能自动和C++
程序使用的库联接,所以通常使用用g++
来编译以求自动完成链接。所以对于C
语言程序的编译,我们应该使用gcc
指令,而编译C++
程序则推荐使用g++
指令
7.2 gcc/g++的四个步骤
gcc、g++
编译器从拿到一个c源文件到生成一个可执行程序,中间一共经历了四个步骤: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18第一步: 进行预处理
deng@itcast:~/share/3rd/1gcc$ gcc -E 1hello.c -o 1hello.i
第二步: 生成汇编文件
deng@itcast:~/share/3rd/1gcc$ gcc -S 1hello.i -o 1hello.s
第三步: 生成目标代码
deng@itcast:~/share/3rd/1gcc$ gcc -c 1hello.s -o 1hello.o
第四步: 生成可以执行文件
//这条指令是完成链接这个过程的,它通过链接器ld将运行程序的目标文件和库文件链接在一起,
//生成最后的可执行文件
deng@itcast:~/share/3rd/1gcc$ gcc 1hello.o -o 1hello
第五步: 执行
deng@itcast:~/share/3rd/1gcc$ ./1hello
hello itcast
也可直接将源文件生成一个可以执行文件
deng@itcast:~/share/3rd/1gcc$ gcc 1hello.c -o 1hello
deng@itcast:~/share/3rd/1gcc$ ./1hello
hello itcast
常用选项 1
2
3
4
5
6
7
8
9
10gcc hello.c -o hello -I /home/hello/include -L /home/hello/lib -lworld
上面这句表示在编译hello.c时:
-I /home/hello/include表示将/home/hello/include目录作为第一个寻找头文件的目录,
寻找的顺序是:/home/hello/include-->/usr/include-->/usr/local/include
-L /home/hello/lib表示将/home/hello/lib目录作为第一个寻找库文件的目录,
寻找的顺序是:/home/hello/lib-->/lib-->/usr/lib-->/usr/local/lib
-lworld表示在上面的lib的路径中寻找libworld.so动态库文件或libworld.a静态库文件
附加:
-I
针对头文件,未指明路径时,使用#include<>
,gcc/g++
默认目录/usr/include
,如果使用#include<my.h>
则找不到my.h
文件,因此要通过-I dir
参数来指定包含的头文件my.h
的位置:1
$gcc hell.c -o hell -I /root (假设文件my.h存放在/root下)
-L
与-I
功能类似,只不过-L
时对库文件使用,能够在指定库文件搜索路径。如果一个程序用到了目录/root/lib
下的一个动态库libsunq.so
,因为-L dir
指定的是路径而没有指定文件,则需要用到-llibname
参数,它可以指定gcc
去寻找libsunq.so
或者libsunq.a
1
$gcc hello.c -o hell -L /root/lib -lsunq
7.3 静态链接和动态链接
7.3.1静态链接
静态链接是指由链接器在链接时将库的内容直接加入到可执行程序中。
- 优点:
- 对运行环境的依赖性较小,具有较好的兼容性
- 缺点:
- 生成的程序比较大,需要更多的系统资源,在装入内存时会消耗更多的时间
- 库函数有了更新,必须重新编译应用程序
7.3.2 动态链接
动态链接是指连接器在链接时仅仅建立与所需库函数的之间的链接关系,在程序运行时才将所需资源调入可执行程序。
- 优点:
- 在需要的时候才会调入对应的资源函数
- 简化程序的升级;有着较小的程序体积
- 实现进程之间的资源共享(避免重复拷贝)
- 缺点:
- 依赖动态库,不能独立运行
- 动态库依赖版本问题严重
注:前面我们编写的应用程序大量用到了标准库函数,系统默认采用动态链接的方式进行编译程序,若想采用静态编译,加入-static
参数。
7.3.3 静态库的制作
静态库可以认为是一些目标代码的集合,是在可执行程序运行前就已经加入到执行码中,成为执行程序的一部分。 按照习惯,一般以.a
做为文件后缀名。静态库的命名一般分为三个部分:
- 前缀:
lib
- 库名称:自己定义即可
- 后缀:
.a
所以最终的静态库的名字应该为:libxxx.a
1
2
3
4
5
6
7步骤1:将c源文件生成对应的.o文件
deng@itcast:~/test/3static_lib$ gcc -c add.c -o add.o
deng@itcast:~/test/3static_lib$ gcc -c sub.c -o sub.o
deng@itcast:~/test/3static_lib$ gcc -c mul.c -o mul.o
deng@itcast:~/test/3static_lib$ gcc -c div.c -o div.o
步骤2:使用打包工具ar将准备好的.o文件打包为.a文件 libtest.a
deng@itcast:~/test/3static_lib$ ar -rcs libAlogrithm.a add.o sub.o mul.o div.o-rcs
r
更新c
创建s
建立索引
7.3.4 静态库的使用
静态库制作完成之后,需要将.a
文件和头文件一起发布给用户。假设测试文件为main.c
,静态库文件为libAlogrithm.a
,头文件为Alogrithm.h
1
2
3
4
5
6
7
8
9
10trluper@trluper-virtual-machine:~/Documents/test$ cat main.cpp
using namespace std;
int main(){
int a=20,b=20;
cout<<sum(a,b)<<endl;
return 0;
}
trluper@trluper-virtual-machine:~/Documents/test$ g++ -static main.cpp -I ../staticLib/ -L ../staticLib/ -lAlogrithm -o test
7.3.5 动图库的制作
共享库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题和更新问题。 按照习惯,一般以“.so”做为文件后缀名。共享库的命名一般分为三个部分:
- 前缀:
lib
- 库名称:自己定义即可
- 后缀:
.so
所以最终的动态库的名字应该为:libxxx.so
1 | 步骤一:生成目标文件,此时要加编译选项:-fPIC(fpic) |
7.3.6 使用动态库
静态库制作完后,需要在测试文件所在的目录创建libxxx.so
的链接接,否则就会出现下面这个错误: 1
error while loading shared libraries: libtiger.so: cannot open shared object file: No such file or direct
ldd
命令查看哪些动态链接库没有找到: 1
2
3
4
5
6
7
8trluper@trluper-virtual-machine:~/Documents/test$ ldd test1
linux-vdso.so.1 (0x00007ffc0d5fe000)
libAlogrithm.so => not found
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fbd2317f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbd22f57000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbd22e70000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbd233c1000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fbd22e50000)
- 方法一是可在系统目录创建软链接,链接文件。这是因为用·
-L
指定动态库文件路径只能保证编译通过,是否能执行还是得看/lib/
或/usr/lib
下面有没有该库文件(只要没有删除,永久有效) - 方法二当然你要可以修改
LD_LIBRARY_PATH
指定的动态库搜索路径(当前shell有效) - 方法三是配置文件
/etc/ld.so.conf
中指定的动态库搜索路径(永久有效)
1 | deng@itcast:~/test/6share_test$ sudo ln -s /home/trluper/Documents/staticLib/libtest.so /lib/share_test/libtest.so |
然后同静态链接一样,引用动态库去编译:(要保证能找到头文件,因此使用-I
) 1
g++ -static main.cpp -I ../staticLib/ -lAlogrithm -o test
7.4 gdb调试
GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。 对于一名Linux下工作的c/c++程序员,gdb是必不可少的工具。GDB主要帮忙你完成下面四个方面的功能:
- 启动程序,可以按照你的自定义的要求随心所欲的运行程序。
- 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
- 当程序被停住时,可以检查此时你的程序中所发生的事。
- 动态的改变你程序的执行环境。
7.4.1 gdb的工作步骤
1. 准备工作
1 | //使用gcc/g++将其编译为可执行文件,同时使用-g表示该程序可调试: |
2. 启动gdb
输入gdb -q + 可执行文件
,启动gdb进行调试。-q
参数可以屏蔽一些gdb版本等相关信息,使得页面看起来干净些(我用了)。至此gdb启动完毕: 1
2
3trluper@trluper-virtual-machine:~/Documents/staticLib$ gdb -q main
Reading symbols from main...
(gdb)
3. 查看代码(可选)
输入list(l)
即可查看程序源码 1
2
3
4
5
6
7
8
9
10(gdb) l
1
2
3 using namespace std;
4 int main()
5 {
6 int a=10,b=20;
7 cout<<sum(a,b)<<endl;
8 return 0;
9 }
4. 设置参数(可选)
set args
可指定运行时参数(如:set args 10 20 30 40 50
)。show args
命令可以查看设置好的运行参数 1
2
3
4
5
6
7(gdb) set args 20 30 50
(gdb) b 2
Breakpoint 1 at 0x11b5: file main.cpp, line 6.
(gdb) run
Starting program: /home/trluper/Documents/staticLib/main 20 30 50
gdb) show args
Argument list to give program being debugged when it is started is "20 30 50".
5.设置断点(可选)
输入break(b)+数字
可以对程序进行断点操作(数字就是设置断点的代码行数) 1
2(gdb) b 2
Breakpoint 1 at 0x11b5: file main.cpp, line 6.
6. 启动程序
输入run(r)
开始运行程序,直到遇到“断点”或者“结束” 1
2
3
4
5
6
7(gdb) r
Starting program: /home/trluper/Documents/staticLib/main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main () at main.cpp:6
6 int a=10,b=20;
7.单步执行程序(可选)
next
单步执行程序,但是遇到函数时会直接跳过函数,不进入函数step
单步执行程序,但遇到函数会进入函数continue
继续执行程序,直到遇到断点或结束
1 | Argument list to give program being debugged when it is started is "20 30 50". |
8. 查看变量值(可选)
print + 变量
查看变量值;whatis + 变量
查看变量数据类型。 1
2
3
4(gdb) print a
$1 = 10
(gdb) whatis a
type = int
9. 退出
输入q
即可退出gdb 1
2
3
4(gdb) q
A debugging session is active.
Inferior 1 [process 3102] will be killed.
Quit anyway? (y or n) y
7.4.2 其他命令
1. 断点
命令 | 功能 |
---|---|
delete + n |
删除第n 个断点 |
disable + n |
暂停第n 个断点 |
enable + n |
开启第n 个断点 |
clear + n |
清除第n 行的断点 |
info b |
显示当前程序的断点设置情况 |
delete breakpoints |
清除所有断点 |
2. 运行信息
命令 | 功能 |
---|---|
where/bt |
当前运行的堆栈列表 |
bt backtrace |
显示当前调用堆栈 |
up/down |
改变堆栈显示的深度 |
info program |
查看程序是否在运行,以及进程号被暂停的原因 |
3. 运行命令
命令 | 功能 |
---|---|
until |
如果你厌倦了在一个循环内单步跟踪,它可以运行程序直到退出循环体 |
until + 行号 |
运行至某行 |
finish |
运行程序,直到当前函数返回完成,并且打印函数返回时的堆栈地址和返回值及参数值等信息 |
call + 行数 + (参数) |
调用程序中可见的函数,并传递参数 |
8. shell脚本
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。对于Linux 的 Shell 种类众多,常见的有:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
在一般情况下,人们并不区分Bourne Shell
和Bourne Again Shell
,所以,像#!/bin/sh,
它同样也可以改为 #!/bin/bash
。#!
告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell
程序。
8.1 创建一个脚本文件
使用vi/vim
命令来创建文件),新建一个文件test.sh
,扩展名为sh
(sh代表shell),扩展名并不影响脚本执行,见名知意就好。输入一些代码,第一行一般是这样: 1
2#!/bin/bash
echo "Hello World !"#!
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell
。echo 命令用于向窗口输出文本。
8.2 运行脚本的方法
8.2.1 作为可执行程序
将上面的代码保存到test.sh
,并cd
到相应目录: 1
2chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本./test.sh
,而不是test.sh
,运行其它二进制的程序也一样,直接写test.sh
的话,linux
系统会去PATH
里寻找有没有叫test.sh
的,而只有 /bin, /sbin, /usr/bin,/usr/sbin
等在PATH
里,你的当前目录通常不在PATH
里,所以写成test.sh
是会找不到命令的,要用 ./test.sh
告诉系统说,就在当前目录找。
8.2.2 作为解释器参数
这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如: 1
2/bin/sh test.sh
/bin/php test.php
8.3 变量
变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则: - 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。 - 中间不能有空格,可以使用下划线 _。 - 不能使用标点符号。 - 不能使用bash里的关键字(可用help命令查看保留关键字)。
定义变量时,变量名不加美元符号$
,但PHP语言中变量需要。使用变量名是需要加$
1
2
3
4
5your_name="runoob.com"
echo $your_name
echo ${your_name}
echo "My name is &{your_name}teacher"
your_name="xiaoming"
- 变量名外面的
{}
是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界, - 一般推荐使用
{}
,比如上面的第三节,如果不加{}
,则会认为your_nameteacher为一个变量名,就出错了。 - 重新赋值是允许的,仍有不用加
$
,只有使用的时候加上$