Linux 笔记
- 操作系统的发展史
- Linux介绍
- 命令行基本操作
- Linux命令
- linux命令练习
- 特殊权限
- linux软件安装
- Shell编程
- 文本编辑命令
- vim全套笔记
- Linux系统启动过程
- 虚拟机
操作系统的发展史
Unix
- 1965年之前,电脑只有军事或者学院的研究机构碰的起,当时大型主机至多能提供30台终端(30个键盘、显示器)的连接。
- 1965年左后由贝尔实验室、麻省理工学院 以及 通用电气共同发起了Multics项目,想让大型主机支持300台终端
- 1969年前后这个项目进度缓慢,资金短缺,贝尔实验室退出了研究
- 1969年从这个项目中退出的Ken Thompson当时在实验室无聊时,为了让一台空闲的电脑上能够运行“星际旅行”游行,在8月份左右趁着其妻子探亲的时间,用了1个月的时间编写出了 Unix操作系统的原型
- 1970年,美国贝尔实验室的 Ken Thompson,以 BCPL语言 为基础,设计出很简单且很接近硬件的 B语言(取BCPL的首字母),并且他用B语言写了第一个UNIX操作系统。
因为B语言的跨平台性较差,为了能够在其他的电脑上也能够运行这个非常棒的Unix操作系统,Dennis Ritchie和Ken Thompson 从B语言的基础上准备研究一个更好的语言 - 1972年,美国贝尔实验室的 Dennis Ritchie在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言
- 1973年初,C语言的主体完成。Thompson和Ritchie迫不及待地开始用它完全重写了现在大名鼎鼎的Unix操作系统
Minix
因为AT&T(通用电气)的政策改变,在Version 7 Unix推出之后,发布新的使用条款,将UNIX源代码私有化,在大学中不再能使用UNIX源代码。Andrew S. Tanenbaum(塔能鲍姆)教授为了能在课堂上教授学生操作系统运作的实务细节,决定在不使用任何AT&T的源代码前提下,自行开发与UNIX兼容的操作系统,以避免版权上的争议。他以小型UNIX(mini-UNIX)之意,将它称为MINIX。
Linux
因为Minix只是教学使用,因此功能并不强,因此Torvalds利用GNU的bash当做开发环境,gcc当做编译工具,编写了Linux内核-v0.02,但是一开始Linux并不能兼容Unix,即Unix上跑的应用程序不能在Linux上跑,即应用程序与内核之间的接口不一致,因为Unix是遵循POSIX规范的,因此Torvalds修改了Linux,并遵循POSIX(Portable Operating System Interface,他规范了应用程序与内核的接口规范); 一开始Linux只适用于386,后来经过全世界的网友的帮助,最终能够兼容多种硬件
操作系统的发展



Minix没有火起来的原因
Minix的创始人说,MINIX 3没有统治世界是源于他在1992年犯下的一个错误,当时他认为BSD必然会一统天下,因为它是一个更稳定和更成熟的系统,其它操作系统难以与之竞争。因此他的MINIX的重心集中在教育上。四名BSD开发者已经成立了一家公司销售BSD系统,他们甚至还有一个有趣的电话号码1-800-ITS-UNIX。然而他们正因为这个电话号码而惹火上身。美国电话电报公司因电话号码而提起诉讼。官司打了三年才解决。在此期间,BSD陷于停滞,而Linux则借此一飞冲天。他的错误在于没有意识官司竟然持续了如此长的时间,以及BSD会因此受到削弱。如果美国电话电报公司没有起诉,Linux永远不会流行起来,BSD将统治世界。
Linux介绍
Linux内核&发行版
Linux内核版本
内核(kernel)是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序,它提供了一个在裸设备与应用程序间的抽象层。
Linux内核版本又分为稳定版和开发版,两种版本是相互关联,相互循环:
- 稳定版:具有工业级强度,可以广泛地应用和部署。新的稳定版相对于较旧的只是修正一些bug或加入一些新的驱动程序。
- 开发版:由于要试验各种解决方案,所以变化很快。
内核源码网址:http://www.kernel.org 所有来自全世界的对Linux源码的修改最终都会汇总到这个网站,由Linus领导的开源社区对其进行甄别和修改最终决定是否进入到Linux主线内核源码中。
Linux发行版本
Linux发行版 (也被叫做 GNU/Linux 发行版) 通常包含了包括桌面环境、办公套件、媒体播放器、数据库等应用软件。
目前市面上较知名的发行版有:Ubuntu、RedHat、CentOS、Debian、Fedora、SuSE、OpenSUSE、Arch Linux、SolusOS 等。

类Unix系统目录结构
Unix没有盘符这个概念,只有一个根目录/,所有文件都在它下面

Linux目录

- /:根目录,一般根目录下只存放目录,在Linux下有且只有一个根目录。所有的东西都是从这里开始。当你在终端里输入“/home”,你其实是在告诉电脑,先从/(根目录)开始,再进入到home目录。
- /bin: /usr/bin: 可执行二进制文件的目录,如常用的命令ls、tar、mv、cat等。
- /boot:放置linux系统启动时用到的一些文件,如Linux的内核文件:/boot/vmlinuz,系统引导管理器:/boot/grub。
- /dev:存放linux系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,常用的是挂载光驱 mount /dev/cdrom /mnt。
- /etc:系统配置文件存放的目录,不建议在此目录下存放可执行文件,重要的配置文件有 /etc/inittab、/etc/fstab、/etc/init.d、/etc/X11、/etc/sysconfig、/etc/xinetd.d。
- /home:系统默认的用户家目录,新增用户账号时,用户的家目录都存放在此目录下,表示当前用户的家目录,edu 表示用户 edu 的家目录。
- /lib: /usr/lib: /usr/local/lib:系统使用的函数库的目录,程序在执行过程中,需要调用一些额外的参数时需要函数库的协助。
- /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存放在该目录下。
用户目录
位于/home/user,称之为用户工作目录或家目录,表示方式:
1 | /home/user |
从/目录开始描述的路径为绝对路径,如:
1 | cd /home |
从当前位置开始描述的路径为相对路径,如:
1 | cd ../../ |
每个目录下都有**.和…**
. 表示当前目录
… 表示上一级目录,即父目录
根目录下的.和…都表示当前目录
| 文件的颜色 | 含义 |
|---|---|
| 蓝色 | 目录 |
| 绿色 | 可执行文件 |
| 红色 | 压缩文件 |
| 浅蓝色 | 链接文件 |
| 灰色 | 其他文件 |
命令行基本操作
命令使用方法
Linux命令格式:
1 | command [-options] [parameter1] … |
command: 命令名; [-options]:选项,可用来对命令进行控制,也可以省略,[]代表可选 parameter1 …:传给命令的参数:可以是零个一个或多个
查看帮助文档
help
一般是linux命令自带的帮助信息
如:ls –help
man(manual)
man是linux提供的一个手册,包含了绝大部分的命令、函数使用说明
该手册分成很多章节(section),使用man时可以指定不同的章节来浏览。
例:man ls ; man 2 printf
man中各个section意义如下:
- Standard commands(标准命令)
- System calls(系统调用,如open,write)
- Library functions(库函数,如printf,fopen)
- Special devices(设备文件的说明,/dev下各种设备)
- File formats(文件格式,如passwd)
- Games and toys(游戏和娱乐)
- Miscellaneous(杂项、惯例与协定等,例如Linux档案系统、网络协定、ASCII 码;environ全局变量)
- Administrative Commands(管理员命令,如ifconfig)
man是按照手册的章节号的顺序进行搜索的。
man设置了如下的功能键:
| 功能键 | 功能 |
|---|---|
| 空格键 | 显示手册页的下一屏 |
| Enter键 | 一次滚动手册页的一行 |
| b | 回滚一屏 |
| f | 前滚一屏 |
| q | 退出man命令 |
| h | 列出所有功能键 |
| /word | 搜索word字符串 |

注意:实际上,我们不用指定第几个章节也用查看,如,man ls
tab键自动补全
在敲出命令的前几个字母的同时,按下tab键,系统会自动帮我们补全命令
history游览历史
当系统执行过一些命令后,可按上下键翻看以前的命令,history将执行过的命令列举出来
history保留了最近执行的命令记录,默认可以保留1000。
历史清单从0开始编号到最大值。
常见用法:
1 | history N 显示最近N条命令 |
命令行中的ctrl组合键
- Ctrl+c 结束正在运行的程序
- Ctrl+d 结束输入或退出shell
- Ctrl+s 暂停屏幕输出【锁住终端】
- Ctrl+q 恢复屏幕输出【解锁终端】
- Ctrl+l 清屏,【是字母L的小写】等同于Clear
- 当前光标到行首:ctrl+a
- 当前光标到行尾:ctrl+e
- 删除当前光标到行首:ctrl+u
- 删除当前光标到行尾:ctrl+k
- Ctrl+y 在光标处粘贴剪切的内容
- Ctrl+r 查找历史命令【输入关键字,就能调出以前执行过的命令】
- Ctrl+t 调换光标所在处与其之前字符位置,并把光标移到下个字符
- Ctrl+x+u 撤销操作
- Ctrl+z 转入后台运行
Linux命令
权限管理
列出目录的内容:ls
Linux文件或者目录名称最长可以有265个字符,“.”代表当前目录,“…”代表上一级目录,以“.”开头的文件为隐藏文件,需要用 -a 参数才能显示。
ls常用参数:
| 参数 | 含义 |
|---|---|
| -a | 显示指定目录下所有子目录与文件,包括隐藏文件 |
| -l | 以列表方式显示文件的详细信息 |
| -h | 配合 -l 以人性化的方式显示文件大小 |
1 | [root@VM_0_9_centos ~]# ll -h |
列出的信息的含义:

ls支持通配符:
| 通配符 | 含义 |
|---|---|
| * | 文件代表文件名中所有字符 |
| ls te* | 查找以te开头的文件 |
| ls *html | 查找结尾为html的文件 |
| ? | 代表文件名中任意一个字符 |
| ls ?.c | 只找第一个字符任意,后缀为.c的文件 |
| ls a.? | 只找只有3个字符,前2字符为a.,最后一个字符任意的文件 |
| [] | [”和“]”将字符组括起来,表示可以匹配字符组中的任意一个。“-”用于表示字符范围。 |
| [abc] | 匹配a、b、c中的任意一个 |
| [a-f] | 匹配从a到f范围内的的任意一个字符 |
| ls [a-f]* | 找到从a到f范围内的的任意一个字符开头的文件 |
| ls a-f | 查找文件名为a-f的文件,当“-”处于方括号之外失去通配符的作用 |
| \ | 如果要使通配符作为普通字符使用,可以在其前面加上转义字符。“?”和“*”处于方括号内时不用使用转义字符就失去通配符的作用。 |
| ls *a | 查找文件名为*a的文件 |
显示inode的内容:stat
1 | stat [文件或目录] |
查看 testfile 文件的inode内容内容,可以用以下命令:
1 | [root@VM_0_9_centos ~]# stat mysql-community-release-el7-5.noarch.rpm |
文件访问权限
用户能够控制一个给定的文件或目录的访问程度,一个文件或目录可能有读、写及执行权限:
- 读权限(r) :对于文件,具有读取文件内容的权限;对于目录,具有浏览目录的权限。
- 写权限(w) :对于文件,具有修改文件内容的权限;对于目录,具有删除、移动目录内文件的权限。
- 可执行权限(x): 对于文件,具有执行文件的权限;对于目录,该用户具有进入目录的权限。
通常,Unix/Linux系统只允许文件的属主(所有者)或超级用户改变文件的读写权限。
示例:

第1个字母代表文件的类型:
- “d” 代表文件夹
- “-” 代表普通文件
- “c” 代表硬件字符设备
- “b” 代表硬件块设备
- “s”表示管道文件
- “l” 代表软链接文件。
后9个字母分别代表三组权限:文件所有者、用户组、其他用户拥有的权限。
修改文件权限:chmod
chmod 修改文件权限有两种使用格式:字母法与数字法。
字母法:chmod u/g/o/a +/-/= rwx 文件
| [ u/g/o/a ] | 含义 |
|---|---|
| u | user 表示该文件的所有者 |
| g | group 表示与该文件的所有者属于同一组( group )者,即用户组 |
| o | other 表示其他以外的人 |
| a | all 表示这三者皆是 |
| [ ±= ] | 含义 |
|---|---|
| + | 增加权限 |
| - | 撤销权限 |
| = | 设定权限 |
| rwx | 含义 |
|---|---|
| r | read 表示可读取,对于一个目录,如果没有r权限,那么就意味着不能通过ls查看这个目录的内容。 |
| w | write 表示可写入,对于一个目录,如果没有w权限,那么就意味着不能在目录下创建新的文件。 |
| x | excute 表示可执行,对于一个目录,如果没有x权限,那么就意味着不能通过cd进入这个目录。 |
数字法:“rwx” 这些权限也可以用数字来代替
| 字母 | 说明 |
|---|---|
| r | 读取权限,数字代号为 “4” |
| w | 写入权限,数字代号为 “2” |
| x | 执行权限,数字代号为 “1” |
| - | 不具任何权限,数字代号为 “0” |
如执行:chmod u=rwx,g=rx,o=r filename 就等同于:chmod u=7,g=5,o=4 filename
chmod 751 file:
- 文件所有者:读、写、执行权限
- 同组用户:读、执行的权限
- 其它用户:执行的权限
chmod 777 file:所有用户拥有读、写、执行权限
注意:如果想递归所有目录加上相同权限,需要加上参数“ -R ”。 如:chmod 777 test/ -R 递归 test 目录下所有文件加 777 权限
修改文件所有者:chown
1 | python@ubuntu:~/test$ ll h.txt |
修改文件所属组:chgrp
1 | python@ubuntu:~/test$ ll h.txt |
文件内容查看
Linux系统中使用以下命令来查看文件的内容:
- cat 由第一行开始显示文件内容
- tac 从最后一行开始显示
- nl 显示的时候,顺道输出行号
- more 一页一页的显示文件内容
- less与more 类似,但可以往前翻页
- head 只看头几行
- tail 只看尾巴几行
基本显示:cat、tac
语法:
1 | cat [-AbEnTv] |
选项与参数:
- -A :相当于 -vET 的整合选项,可列出一些特殊字符而不是空白而已;
- -v :列出一些看不出来的特殊字符
- -E :将结尾的断行字节 $ 显示出来;
- -T :将 [tab] 按键以 ^I 显示出来;
- -b :列出行号,空白行不标行号
- -n :列出行号,连同空白行也会有行号
1 | [root@VM_0_9_centos ~]# cat -b /etc/issue |
tac与cat命令刚好相反,文件内容从最后一行开始显示,可以看出 tac 是 cat 的倒着写!如:
1 | [root@VM_0_9_centos ~]# tac /etc/issue |
显示行号:nl
语法:
1 | nl [-bnw] 文件 |
选项与参数:
- -b :指定行号指定的方式,主要有两种:
-b a :表示不论是否为空行,也同样列出行号(类似 cat -n);
-b t :如果有空行,空的那一行不要列出行号(默认值); - -n :列出行号表示的方法,主要有三种:
-n ln :行号在荧幕的最左方显示;
-n rn :行号在自己栏位的最右方显示,且不加 0 ;
-n rz :行号在自己栏位的最右方显示,且加 0 ; - -w :行号栏位的占用的位数。
1 | [root@www ~]# nl /etc/issue |
分屏显示:more、less
1 | [root@www ~]# more /etc/man_db.config |
more运行时可以输入的命令有:
- 空白键 (space):代表向下翻一页;
- Enter :代表向下翻『一行』;
- /字串 :代表在这个显示的内容当中,向下搜寻『字串』这个关键字;
- :f :立刻显示出档名以及目前显示的行数;
- q :代表立刻离开 more ,不再显示该文件内容。
- b 或 [ctrl]-b :代表往回翻页,不过这动作只对文件有用,对管线无用。
1 | [root@www ~]# less /etc/man.config |
less运行时可以输入的命令有:
- 空白键 :向下翻动一页;
- [pagedown]:向下翻动一页;
- [pageup] :向上翻动一页;
- /字串 :向下搜寻『字串』的功能;
- ?字串 :向上搜寻『字串』的功能;
- n :重复前一个搜寻 (与 / 或 ? 有关!)
- N :反向的重复前一个搜寻 (与 / 或 ? 有关!)
- q :离开 less 这个程序;
取首尾n行:head、tail
head取出文件前面几行
语法:
1 | head [-n number] 文件 |
选项与参数:
- -n :后面接数字,代表显示几行的意思
1 | [root@www ~]# head /etc/man.config |
默认的情况中,显示前面 10 行!若要显示前 20 行,就得要这样:
1 | [root@www ~]# head -n 20 /etc/man.config |
tail取出文件后面几行
语法:
1 | tail [-n number] 文件 |
选项与参数:
- -n :后面接数字,代表显示几行的意思
- -f :表示持续侦测后面所接的档名,要等到按下[ctrl]-c才会结束tail的侦测
1 | [root@www ~]# tail /etc/man.config |
文件管理
输出重定向:>
可将本应显示在终端上的内容保存到指定文件中。
如:ls > test.txt ( test.txt 如果不存在,则创建,存在则覆盖其内容 )
注意: >输出重定向会覆盖原来的内容,>>输出重定向则会追加到文件的尾部。
管道:|
管道:一个命令的输出可以通过管道做为另一个命令的输入。
“ | ”的左右分为两端,从左端写入到右端。
1 | python@ubuntu:/bin$ ll -h |more |
清屏:clear
clear作用为清除终端上的显示(类似于DOS的cls清屏功能),快捷键:Ctrl + l ( “l” 为字母 )。
切换工作目录: cd
1 | Linux所有的目录和文件名大小写敏感 |
cd后面可跟绝对路径,也可以跟相对路径。如果省略目录,则默认切换到当前用户的主目录。
| 命令 | 含义 |
|---|---|
| cd | 相当于cd ~ |
| cd ~ | 切换到当前用户的主目录(/home/用户目录) |
| cd . | 切换到当前目录 |
| cd … | 切换到上级目录 |
| cd - | 进入上次所在的目录 |
显示当前路径:pwd
1 | python@ubuntu:~$ pwd |
选项与参数:
- -P :显示出确实的路径,而非使用连结 (link) 路径。
1 | [root@VM_0_9_centos ~]# cd /var/mail/ |
创建目录:mkdir
mkdir可以创建一个新的目录。
注意:新建目录的名称不能与当前目录中已有的目录或文件同名,并且目录创建者必须对当前目录具有写权限。
语法:
1 | mkdir [-mp] 目录名称 |
选项与参数:
- -m :指定被创建目录的权限,而不是根据默认权限 (umask) 设定
- -p :递归创建所需要的目录
实例:-p递归创建目录:
1 | [root@www ~]# cd /tmp |
mkdir创建的目录权限默认根据umask得到,而-m参数可以指定被创建目录的权限:
1 | [root@VM_0_9_centos ~]# mkdir t1 |
删除文件:rm
可通过rm删除文件或目录。使用rm命令要小心,因为文件删除后不能恢复。为了防止文件误删,可以在rm后使用-i参数以逐个确认要删除的文件。
常用参数及含义如下表所示:
| 参数 | 含义 |
|---|---|
| -i | 以进行交互式方式执行 |
| -f | 强制删除,忽略不存在的文件,无需提示 |
| -r | 递归地删除目录下的内容,删除文件夹时必须加此参数 |
建立链接文件:ln
软链接:ln -s 源文件 链接文件
硬链接:ln 源文件 链接文件
软链接类似于Windows下的快捷方式,如果软链接文件和源文件不在同一个目录,源文件要使用绝对路径,不能使用相对路径。
硬链接只能链接普通文件不能链接目录。 两个文件占用相同大小的硬盘空间,即使删除了源文件,链接文件还是存在,所以-s选项是更常见的形式。
文本搜索:grep
Linux系统中grep命令是一种强大的文本搜索工具,grep允许对文本文件进行模式查找。如果找到匹配模式, grep打印包含模式的所有行。
grep一般格式为:
1 | grep [-选项] '搜索内容串' 文件名 |
在grep命令中输入字符串参数时,最好引号或双引号括起来。例如:grep 'a' 1.txt。
在当前目录中,查找前缀有test字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令:
1 | $ grep test test* #查找前缀有test的文件包含test字符串的文件 |
以递归的方式查找符合条件的文件。例如,查找指定目录/etc/acpi 及其子目录(如果存在子目录的话)下所有文件中包含字符串”update”的文件,并打印出该字符串所在行的内容,使用的命令为:
1 | $ grep -r update /etc/acpi #以递归的方式查找“etc/acpi” |
反向查找。前面各个例子是查找并打印出符合条件的行,通过”-v”参数可以打印出不符合条件行的内容。
查找文件名中包含 test 的文件中不包含test 的行,此时,使用的命令为:
1 | $ grep -v test* #查找文件名中包含test 的文件中不包含test 的行 |
查找文件:find
常用用法:
| 命令 | 含义 |
|---|---|
| find ./ -name test.sh | 查找当前目录下所有名为test.sh的文件 |
| find ./ -name ‘*.sh’ | 查找当前目录下所有后缀为.sh的文件 |
| find ./ -name “[A-Z]*” | 查找当前目录下所有以大写字母开头的文件 |
| find /tmp -size 2M | 查找在/tmp 目录下等于2M的文件 |
| find /tmp -size +2M | 查找在/tmp 目录下大于2M的文件 |
| find /tmp -size -2M | 查找在/tmp 目录下小于2M的文件 |
| find ./ -size +4k -size -5M | 查找当前目录下大于4k,小于5M的文件 |
| find ./ -perm 0777 | 查找当前目录下权限为 777 的文件或目录 |
Linux find命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。
语法:
1 | find path -option [ -print ] [ -exec -ok command ] {} \; |
常用参数说明 :
- -perm xxxx:权限为 xxxx的文件或目录
- -user: 按照文件属主来查找文件。
- -size n : n单位,b:512位元组的区块,c:字元数,k:kilo bytes,w:二个位元组
- -mount, -xdev : 只检查和指定目录在同一个文件系统下的文件,避免列出其它文件系统中的文件
- -amin n : 在过去 n 分钟内被读取过
- -anewer file : 比文件 file 更晚被读取过的文件
- -atime n : 在过去n天内被读取过的文件
- -cmin n : 在过去 n 分钟内被修改过
- -cnewer file :比文件 file 更新的文件
- -ctime n : 在过去n天内被修改过的文件
- -empty : 空的文件
- -gid n or -group name : gid 是 n 或是 group 名称是 name
- -ipath p, -path p : 路径名称符合 p 的文件,ipath 会忽略大小写
- -name name, -iname name : 文件名称符合 name 的文件。iname 会忽略大小写
- -type 查找某一类型的文件:
- b - 块设备文件
- d - 目录
- c - 字符设备文件
- p - 管道文件
- l - 符号链接文件
- f - 普通文件
- -exec 命令名{} \ (注意:“}”和“\”之间有空格)
find实例:
显示当前目录中大于20字节并以.c结尾的文件名
1 | find . -name "*.c" -size +20c |
将目前目录其其下子目录中所有一般文件列出
1 | find . -type f |
将目前目录及其子目录下所有最近 20 天内更新过的文件列出
1 | find . -ctime -20 |
查找/var/log目录中更改时间在7日以前的普通文件,并在删除之前询问它们:
1 | find /var/log -type f -mtime +7 -ok rm {} \; |
查找前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件:
1 | find . -type f -perm 644 -exec ls -l {} \; |
查找系统中所有文件长度为0的普通文件,并列出它们的完整路径:
1 | find / -type f -size 0 -exec ls -l {} \; |
从根目录查找类型为符号链接的文件,并将其删除:
1 | find / -type l -exec rm -rf {} \ |
从当前目录查找用户tom的所有文件并显示在屏幕上
1 | find . -user tom |
在当前目录中查找所有文件以.doc结尾,且更改时间在3天以上的文件,找到后删除,并且给出删除提示
1 | find . -name *.doc -mtime +3 -ok rm {} \; |
在当前目录下查找所有链接文件,并且以长格式显示文件的基本信息
1 | find . -type l -exec ls -l {} \; |
在当前目录下查找文件名有一个小写字母、一个大写字母、两个数字组成,且扩展名为.doc的文件
1 | find . -name '[a-z][A-Z][0-9][0-9].doc' |
拷贝文件:cp
cp命令的功能是将给出的文件或目录复制到另一个文件或目录中,相当于DOS下的copy命令。
常用选项说明:
| 选项 | 含义 |
|---|---|
| -a | 该选项通常在复制目录时使用,它保留链接、文件属性,并递归地复制目录,简单而言,保持文件原有属性。 |
| -f | 已经存在的目标文件而不提示 |
| -i | 交互式复制,在覆盖目标文件之前将给出提示要求用户确认 |
| -r | 若给出的源文件是目录文件,则cp将递归复制该目录下的所有子目录和文件,目标文件必须为一个目录名。 |
| -v | 显示拷贝进度 |
| -l | 创建硬链接(hard link),而非复制文件本身 |
| -s | 复制成为符号链接 (symbolic link),相当于批量创建快捷方式 |
| -u | 若 destination 比 source 旧才升级 destination ! |
cp vim_configure/ code/ -ivr 把文件夹 vim_configure 拷贝到 code 目录里。
移动文件:mv
mv命令用来移动文件或目录,也可以给文件或目录重命名。
常用选项说明:
| 选项 | 含义 |
|---|---|
| -f | 禁止交互式操作,如有覆盖也不会给出提示 |
| -i | 确认交互方式操作,如果mv操作将导致对已存在的目标文件的覆盖,系统会询问是否重写,要求用户回答以避免误覆盖文件 |
| -v | 显示移动进度 |
归档管理:tar
此命令可以把一系列文件归档到一个大文件中,也可以把档案文件解开以恢复数据。
tar使用格式 tar [参数] 打包文件名 文件
tar命令参数很特殊,其参数前面可以使用“-”,也可以不使用。
常用参数:
| 参数 | 含义 |
|---|---|
| -c | 生成档案文件,创建打包文件 |
| -v | 列出归档解档的详细过程,显示进度 |
| -f | 指定档案文件名称,f后面一定是.tar文件,所以必须放选项最后 |
| -t | 列出档案中包含的文件 |
| -x | 解开档案文件 |
注意:除了f需要放在参数的最后,其它参数的顺序任意。
1 | python@ubuntu:~/test$ tar -cvf test.tar 1.txt 2.txt 3.txt |
文件压缩解压:gzip、bzip2
tar与gzip命令结合使用实现文件打包、压缩。 tar只负责打包文件,但不压缩,用gzip压缩tar打包后的文件,其扩展名一般用xxxx.tar.gz。
gzip使用格式如下:
1 | gzip [选项] 被压缩文件 |
常用选项:
| 选项 | 含义 |
|---|---|
| -d | 解压文件 |
| -r | 压缩文件 |
1 | python@ubuntu:~/test$ ll *.tar* |
tar命令中-z选项可以调用gzip实现了一个压缩的功能,实行一个先打包后压缩的过程。
压缩用法:tar zcvf 压缩包包名 文件1 文件2 …
例如: tar zcvf test.tar.gz 1.c 2.c 3.c 4.c把 1.c 2.c 3.c 4.c 压缩成 test.tar.gz
1 | python@ubuntu:~/test/code$ ls |
解压用法: tar zxvf 压缩包包名
例如:
1 | python@ubuntu:~/test/code$ ls |
解压到指定目录:-C (解压时可以不指定-z选项)
1 | python@ubuntu:~/test/code$ ls number/ |
bzip2命令跟gzip用法类似
压缩用法:tar jcvf 压缩包包名 文件…(tar jcvf bk.tar.bz2 *.c)
解压用法:tar jxvf 压缩包包名 (tar jxvf bk.tar.bz2)
文件压缩解压:zip、unzip
通过zip压缩文件的目标文件不需要指定扩展名,默认扩展名为zip。
压缩文件:zip [-r] 目标文件(没有扩展名) 源文件
解压文件:unzip -d 解压后目录文件 压缩文件
1 | python@ubuntu:~/test$ ls |
查看命令位置:which
1 | python@ubuntu:~$ which ls |
用户和用户组管理
用户管理包括用户与组账号的管理。
在Unix/Linux系统中,不论是由本机或是远程登录系统,每个系统都必须拥有一个账号,并且对于不同的系统资源拥有不同的使用权限。
Unix/Linux系统中的root账号通常用于系统的维护和管理,它对Unix/Linux操作系统的所有部分具有不受限制的访问权限。
在Unix/Linux安装的过程中,系统会自动创建许多用户账号,而这些默认的用户就称为“标准用户”。
在大多数版本的Unix/Linux中,都不推荐直接使用root账号登录系统。
查看当前用户:whoami
查看当前系统当前账号的用户名。可通过cat /etc/passwd查看系统用户信息。
1 | python@ubuntu:~/test$ whoami |
查看登录用户:who
who命令用于查看当前所有登录系统的用户信息。
常用选项:
| 选项 | 含义 |
|---|---|
| -m或am I | 只显示运行who命令的用户名、登录终端和登录时间 |
| -q或–count | 只显示用户的登录账号和登录用户的数量 |
| -u | 在登录时间后显示该用户最后一次操作到当前的时间间隔 |
| -u或–heading | 显示列标题 |
退出登录账户: exit
如果是图形界面,退出当前终端;
如果是使用ssh远程登录,退出登陆账户;
如果是切换后的登陆用户,退出则返回上一个登陆账号。
添加用户账号:useradd
在Unix/Linux中添加用户账号可以使用adduser或useradd命令,因为adduser命令是指向useradd命令的一个链接,因此,这两个命令的使用格式完全一样。
useradd命令的使用格式如下: useradd [参数] 新建用户账号
| 参数 | 含义 |
|---|---|
| -d | 指定用户登录系统时的主目录 |
| -m | 自动建立目录,未指定-d参数时会在/home/{当前用户}目录下建立主目录 |
| -g | 指定组名称 |
相关说明:
- Linux每个用户都要有一个主目录,主目录就是第一次登陆系统,用户的默认当前目录(/home/用户);
- 每一个用户必须有一个主目录,所以用useradd创建用户的时候,一定给用户指定一个主目录;
- 如果创建用户的时候,不指定组名,那么系统会自动创建一个和用户名一样的组名。
若创建用户时未指定家目录,后期可通过usermod -d /home/abc abc指定
| 命令 | 含义 |
|---|---|
| useradd -d /home/abc abc -m | 创建abc用户,如果/home/abc目录不存在,就自动创建这个目录,同时用户属于abc组 |
| useradd -d /home/a a -g test -m | 创建一个用户名字叫a,主目录在/home/a,如果主目录不存在,就自动创建主目录,同时用户属于test组 |
| cat /etc/passwd | 查看系统当前用户名 |
修改用户:usermod
常用的选项包括-c, -d, -m, -g, -G, -s, -u以及-o等,这些选项的意义与useradd命令中的选项一样,可以为用户指定新的资源值 。
修改用户所在组:usermod -g 用户组 用户名
1 | usermod -g test abc |
改abc用户的家目录位置:usermod -d 家目录 用户名
1 | usermod -d /home/abc abc |
选项-l 新用户名指定一个新的账号,可修改用户名:
1 | python@ubuntu:~/txt$ tail /etc/passwd -n 1 |
设置用户密码:passwd
超级用户可以为自己和其他用户指定口令,普通用户只能用它修改自己的口令。命令的格式为:
1 | passwd 选项 用户名 |
可使用的选项:
- -l 锁定口令,即禁用账号。
- -u 口令解锁。
- -d 使账号无口令。
- -f 强迫用户下次登录时修改口令。
假设当前用户是sam,则下面的命令修改该用户自己的口令:
1 | $ passwd |
如果是超级用户,可以用下列形式指定任何用户的口令:
1 | # passwd sam |
普通用户修改自己的口令时,passwd命令会先询问原口令,验证后再要求用户输入两遍新口令,如果两次输入的口令一致,则将这个口令指定给用户;而超级用户为用户指定口令时,就不需要知道原口令。
为用户指定空口令时,执行下列形式的命令:
1 | passwd -d sam |
此命令将用户 sam 的口令删除,这样用户 sam 下一次登录时,系统就不再允许该用户登录了。
passwd 命令还可以用 -l(lock) 选项锁定某一用户,使其不能登录,例如:
1 | passwd -l sam |
删除用户:userdel
| 命令 | 含义 |
|---|---|
| userdel abc(用户名) | 删除abc用户,但不会自动删除用户的主目录 |
| userdel -r abc(用户名) | 删除用户,同时删除用户的主目录 |
切换用户:su
su后面可以加“-”会将当前的工作目录自动转换到切换后的用户主目录.
| 命令 | 含义 |
|---|---|
| su | 切换到root用户 |
| su root | 切换到root用户 |
| su - | 切换到root用户,同时切换目录到/root |
| su - root | 切换到root用户,同时切换目录到/root |
| su 普通用户 | 切换到普通用户 |
| su - 普通用户 | 切换到普通用户,同时切换普通用户所在的目录 |
注意:对于ubuntu平台,只能通过sudo su进入root账号。
sudo允许系统管理员让普通用户执行一些或者全部的root命令的一个工具。
以root身份执行指令:sudo
sudo命令可以临时获取root权限
使用权限:在 /etc/sudoers 中有出现的使用者。
1 | 显示出自己(执行 sudo 的使用者)的权限 |
sudoers文件配置语法
1 | user MACHINE=COMMANDS |
例子:
1 | 允许root用户执行任意路径下的任意命令 |
添加、删除组账号:groupadd、groupdel
groupadd 新建组账号 groupdel 组账号 cat /etc/group 查看用户组
1 | python@ubuntu:~/test$ sudo groupadd abc |
用户组管理:groupmod
修改用户组的属性使用groupmod命令。其语法如下:
1 | groupmod 选项 用户组 |
常用的选项有:
- -g GID 为用户组指定新的组标识号。
- -o 与-g选项同时使用,用户组的新GID可以与系统已有用户组的GID相同。
- -n新用户组 将用户组的名字改为新名字
将组group2的组标识号修改为102:
1 | groupmod -g 102 group2 |
将组group2的标识号改为10000,组名修改为group3:
1 | groupmod –g 10000 -n group3 group2 |
如果一个用户同时属于多个用户组,那么用户可以在用户组之间切换,以便具有其他用户组的权限。
用户可以在登录后,使用命令newgrp切换到其他用户组,这个命令的参数就是目的用户组。例如:
1 | $ newgrp root |
这条命令将当前用户切换到root用户组,前提条件是root用户组确实是该用户的主组或附加组。类似于用户账号的管理,用户组的管理也可以通过集成的系统管理工具来完成。
系统管理
查看当前日历:cal
cal命令用于查看当前日历,-y显示整年日历:
1 | python@ubuntu:~$ cal |
显示或设置时间:date
设置时间格式(需要管理员权限):
1 | date [MMDDhhmm[[CC]YY][.ss]] +format |
MM为月,DD为天,hh为小时,mm为分钟;CC为年前两位,YY为年的后两位,ss为秒。
如: date 010203042016.55。
显示时间格式(date ‘+%y,%m,%d,%H,%M,%S’):
| format格式 | 含义 |
|---|---|
| %Y,%y | 年 |
| %m | 月 |
| %d | 日 |
| %H | 时 |
| %M | 分 |
| %S | 秒 |
查看网络状态:netstat
netstat命令用于显示网络状态。
利用netstat指令可让你得知整个Linux系统的网络情况。
语法:
1 | netstat [-acCeFghilMnNoprstuvVwx][-A<网络类型>][--ip] |
参数说明:
- -a或–all 显示所有连线中的Socket。
- -A<网络类型>或–<网络类型> 列出该网络类型连线中的相关地址。
- -c或–continuous 持续列出网络状态。
- -C或–cache 显示路由器配置的快取信息。
- -e或–extend 显示网络其他相关信息。
- -F或–fib 显示FIB。
- -g或–groups 显示多重广播功能群组组员名单。
- -h或–help 在线帮助。
- -i或–interfaces 显示网络界面信息表单。
- -l或–listening 显示监控中的服务器的Socket。
- -M或–masquerade 显示伪装的网络连线。
- -n或–numeric 直接使用IP地址,而不通过域名服务器。
- -N或–netlink或–symbolic 显示网络硬件外围设备的符号连接名称。
- -o或–timers 显示计时器。
- -p或–programs 显示正在使用Socket的程序识别码和程序名称。
- -r或–route 显示Routing Table。
- -s或–statistice 显示网络工作信息统计表。
- -t或–tcp 显示TCP传输协议的连线状况。
- -u或–udp 显示UDP传输协议的连线状况。
- -v或–verbose 显示指令执行过程。
- -V或–version 显示版本信息。
- -w或–raw 显示RAW传输协议的连线状况。
- -x或–unix 此参数的效果和指定”-A unix”参数相同。
- –ip或–inet 此参数的效果和指定”-A inet”参数相同。
常用:
1 | [root@VM_0_9_centos ~]# netstat -nltp |
查看进程信息:ps
进程是一个具有一定独立功能的程序,它是操作系统动态执行的基本单元。
ps命令选项:
- ps a 显示现行终端机下的所有程序,包括其他用户的程序。
- ps -A 显示所有程序。
- ps c 列出程序时,显示每个程序真正的指令名称,而不包含路 径,参数或常驻服务的标示。
- ps -e 此参数的效果和指定”A”参数相同。
- ps e 列出程序时,显示每个程序所使用的环境变量。
- ps f 用ASCII字符显示树状结构,表达程序间的相互关系。
- ps -H 显示树状结构,表示程序间的相互关系。
- ps -N 显示所有的程序,除了执行ps指令终端机下的程序之外。
- ps s 采用程序信号的格式显示程序状况。
- ps u 以用户为主的格式来显示程序状况。
- ps x 显示所有程序,不以终端机来区分。
| 选项 | 含义 |
|---|---|
| -a | 显示终端上的所有进程,包括其他用户的进程 |
| -u | 显示进程的详细状态 |
| -x | 显示没有控制终端的进程 |
| -w | 显示加宽,以便显示更多的信息 |
| -r | 只显示正在运行的进程 |
常见用法:
- ps -e 查看所有进程信息(瞬时的)
- ps -u root -N 查看所有不是root运行的进程
- ps ax 显示所有进程状态状态
- ps -ef |grep xxx 显示含有xxx的进程
实例:
1 | # ps -A 显示进程信息 |
显示指定用户信息:
1 | # ps -u root //显示root进程用户信息 |
显示所有进程信息,连同命令行
1 | # ps -ef //显示所有命令,连带命令行 |
以树状图显示进程关系:pstree
显示进程的关系
1 | pstree |
特别表明在运行的进程:
1 | # pstree -apnh //显示进程间的关系 |
同时显示用户名称:
1 | # pstree -u //显示用户名称 |
动态显示进程:top
top命令用来动态显示运行中的进程。top命令能够在运行后,在指定的时间间隔更新显示信息。-d参数可以指定显示信息更新的时间间隔。
在top命令执行后,可以按下按键得到对显示的结果进行排序:
| 按键 | 含义 |
|---|---|
| M | 根据内存使用量来排序 |
| P | 根据CPU占有率来排序 |
| T | 根据进程运行时间的长短来排序 |
| U | 可以根据后面输入的用户名来筛选进程 |
| K | 可以根据后面输入的PID来杀死进程。 |
| q | 退出 |
| h | 获得帮助 |
1 | python@ubuntu:~$ top |
更高级的命令是htop,但需要安装:
1 | [root@VM_0_9_centos ~]# htop |
终止进程:kill
kill命令指定进程号的进程,需要配合 ps 使用。
使用格式:
1 | kill [-signal] pid |
信号值从0到15,其中9为绝对终止,可以处理一般信号无法终止的进程。
关机重启:reboot、shutdown、init
| 命令 | 含义 |
|---|---|
| reboot | 重新启动操作系统 |
| shutdown –r now | 重新启动操作系统,shutdown会给别的用户提示 |
| shutdown -h now | 立刻关机,其中now相当于时间为0的状态 |
| shutdown -h 20:25 | 系统在今天的20:25 会关机 |
| shutdown -h +10 | 系统再过十分钟后自动关机 |
| init 0 | 关机 |
| init 6 | 重启 |
检测磁盘空间:df
df命令用于检测文件系统的磁盘空间占用和空余情况,可以显示所有文件系统对节点和磁盘块的使用情况。
| 选项 | 含义 |
|---|---|
| -a | 显示所有文件系统的磁盘使用情况 |
| -m | 以1024字节为单位显示 |
| -t | 显示各指定文件系统的磁盘空间使用情况 |
| -T | 显示文件系统 |
1 | python@ubuntu:~/test$ df -Th |
检测目录所占磁盘空间:du
du命令用于统计目录或文件所占磁盘空间的大小,该命令的执行结果与df类似,du更侧重于磁盘的使用状况。
du命令的使用格式如下: du [选项] 目录或文件名
| 选项 | 含义 |
|---|---|
| -a | 递归显示指定目录中各文件和子目录中文件占用的数据块 |
| -s | 显示指定文件或目录占用的数据块 |
| -b | 以字节为单位显示磁盘占用情况 |
| -l | 计算所有文件大小,对硬链接文件计算多次 |
1 | python@ubuntu:~$ du -sh /home/ |
查看或配置网卡信息:ifconfig
ifconfig显示所有网卡的信息:
1 | python@ubuntu:~$ ifconfig |
修改ip:
1 | python@ubuntu:~$ sudo ifconfig ens33 192.168.40.10 |
测试远程主机连通性:ping
1 | python@ubuntu:~$ ping 192.168.40.1 |
Linux 磁盘管理
Linux磁盘管理常用三个命令为df、du和fdisk。
- df:列出文件系统的整体磁盘使用量
- du:检查磁盘空间使用量
- fdisk:用于磁盘分区
df
获取硬盘被占用了多少空间,目前还剩下多少空间等信息。
语法:
1 | df [-ahikHTm] [目录或文件名] |
选项与参数:
- -a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
- -k :以 KBytes 的容量显示各文件系统;
- -m :以 MBytes 的容量显示各文件系统;
- -h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
- -H :以 M=1000K 取代 M=1024K 的进位方式;
- -T :显示文件系统类型, 连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;
- -i :不用硬盘容量,而以 inode 的数量来显示
1 | [root@VM_0_9_centos ~]# df -hT |
将系统内的所有特殊文件格式及名称都列出来
1 | [root@www ~]# df -aT |
du
du命令是对文件和目录磁盘使用的空间的查看.
语法:
1 | du [-ahskm] 文件或目录名称 |
选项与参数:
- -a :列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。
- -h :以人们较易读的容量格式 (G/M) 显示;
- -s :列出总量而已,而不列出每个各别的目录占用容量;
- -S :不包括子目录下的总计,与 -s 有点差别。
- -k :以 KBytes 列出容量显示;
- -m :以 MBytes 列出容量显示;
du没有加任何选项时,只列出当前目录下的所有文件夹容量(包括隐藏文件夹):
1 | [root@www ~]# du |
直接输入 du 没有加任何选项时,则 du 会分析当前所在目录的文件与目录所占用的硬盘空间。
加-a选项才显示文件的容量:
1 | [root@www ~]# du -a |
检查根目录底下每个目录所占用的容量
1 | [root@www ~]# du -sh /* |
fdisk
fdisk 是 Linux 的磁盘分区表操作工具。
语法:
1 | fdisk [-l] 装置名称 |
选项与参数:
- -l :输出后面接的装置所有的分区内容。若仅有 fdisk -l 时, 则系统将会把整个系统内能够搜寻到的装置的分区均列出来。
列出所有分区信息:
1 | [root@AY120919111755c246621 tmp]# fdisk -l |
查看根目录所在磁盘,并查阅该硬盘内的相关信息:
1 | [root@www ~]# df / <==注意:重点在找出磁盘文件名而已 |
输入 m 后,就会看到底下这些命令介绍
1 | Command (m for help): m <== 输入 m 后,就会看到底下这些命令介绍 |
离开 fdisk 时按下 q,那么所有的动作都不会生效!相反的, 按下w就是动作生效的意思。
1 | Command (m for help): p <== 这里可以输出目前磁盘的状态 |
使用 p 可以列出目前这颗磁盘的分割表信息,这个信息的上半部在显示整体磁盘的状态。
磁盘格式化
磁盘分割完毕后自然就是要进行文件系统的格式化,格式化的命令非常的简单,使用 mkfs(make filesystem) 命令。
语法:
1 | mkfs [-t 文件系统格式] 装置文件名 |
选项与参数:
- -t :可以接文件系统格式,例如 ext3, ext2, vfat 等(系统有支持才会生效)
查看 mkfs 支持的文件格式:
1 | [root@VM_0_9_centos web]# mkfs[tab] |
按下两个[tab],会发现 mkfs 支持的文件格式如上所示。
将分区 /dev/hdc6(可指定其他分区) 格式化为ext3文件系统:
1 | [root@www ~]# mkfs -t ext3 /dev/hdc6 |
磁盘检验
fsck(file system check)用来检查和维护不一致的文件系统。
若系统掉电或磁盘发生问题,可利用fsck命令对文件系统进行检查。
语法:
1 | fsck [-t 文件系统] [-ACay] 装置名称 |
选项与参数:
- -t : 给定档案系统的型式,若在 /etc/fstab 中已有定义或 kernel 本身已支援的则不需加上此参数
- -s : 依序一个一个地执行 fsck 的指令来检查
- -A : 对/etc/fstab 中所有列出来的 分区(partition)做检查
- -C : 显示完整的检查进度
- -d : 打印出 e2fsck 的 debug 结果
- -p : 同时有 -A 条件时,同时有多个 fsck 的检查一起执行
- -R : 同时有 -A 条件时,省略 / 不检查
- -V : 详细显示模式
- -a : 如果检查有错则自动修复
- -r : 如果检查有错则由使用者回答是否修复
- -y : 选项指定检测每个文件是自动输入yes,在不确定那些是不正常的时候,可以执行 # fsck -y 全部检查修复。
查看系统有多少文件系统支持的 fsck 命令:
1 | [root@www ~]# fsck[tab][tab] |
强制检测 /dev/hdc6 分区:
1 | [root@www ~]# fsck -C -f -t ext3 /dev/hdc6 |
如果没有加上 -f 的选项,则由于这个文件系统不曾出现问题,检查的经过非常快速!若加上 -f 强制检查,才会一项一项的显示过程。
磁盘挂载与卸除
Linux 的磁盘挂载使用 mount 命令,卸载使用 umount 命令。
磁盘挂载语法:
1 | mount [-t 文件系统] [-L Label名] [-o 额外选项] [-n] 装置文件名 挂载点 |
用默认的方式,将刚刚创建的 /dev/hdc6 挂载到 /mnt/hdc6 上面!
1 | [root@www ~]# mkdir /mnt/hdc6 |
磁盘卸载命令 umount 语法:
1 | umount [-fn] 装置文件名或挂载点 |
选项与参数:
- -f :强制卸除!可用在类似网络文件系统 (NFS) 无法读取到的情况下;
- -n :不升级 /etc/mtab 情况下卸除。
卸载/dev/hdc6
1 | [root@www ~]# umount /dev/hdc6 |
Linux管道命令
Linux的管道命令是’|’,通过它可以对数据进行连续处理,其示意图如下:

注意:
1)管道命令仅处理标准输出,对于标准错误输出,将忽略
2)管道命令右边命令,必须能够接收标准输入流命令才行,否则传递过程中数据会抛弃。
常用来作为接收数据管道命令有: less,more,head,tail,而ls, cp, mv就不行。
wc - 统计字数
可以计算文件的Byte数、字数、或是列数,若不指定文件名称、或是所给予的文件名为”-“,则wc指令会从标准输入设备读取数据。
1 | wc [-lwm] [filename] |
在默认的情况下,wc将计算指定文件的行数、字数,以及字节数。使用的命令为:
1 | $ wc testfile # testfile文件的统计信息 |
其中,3 个数字分别表示testfile文件的行数、单词数,以及该文件的字节数。
如果想同时统计多个文件的信息,例如同时统计testfile、testfile_1、testfile_2,可使用如下命令:
1 | $ wc testfile testfile_1 testfile_2 #统计三个文件的信息 |
cut - 列选取命令
1 | 选项与参数: |
cut以行为单位,根据分隔符把行分成若干列,这样就可以指定选取哪些列了。
1 | cut -d '分隔字符' -f 选取的列数 |
只显示/etc/passwd的用户和shell:
1 | #cat /etc/passwd | cut -d ':' -f 1,7 |
grep - 行选取命令
grep一般格式为:
1 | grep [-cinv] '查找的字符串' filename |
在grep命令中输入字符串参数时,最好引号或双引号括起来。例如:grep 'a' 1.txt。
常用选项说明:
| 选项 | 含义 |
|---|---|
| -v | 显示不包含匹配文本的所有行(相当于求反) |
| -n | 显示匹配行及行号 |
| -i | 忽略大小写 |
| -c | 计算找到的行数 |
grep搜索内容串可以是正则表达式,常用正则表达式:
| 参数 | 含义 |
|---|---|
| ^a | 行首,搜寻以 m 开头的行;grep -n ‘^a’ 1.txt |
| ke$ | 行尾,搜寻以 ke 结束的行;grep -n ‘ke$’ 1.txt |
| [Ss]igna[Ll] | 匹配 [] 里中一系列字符中的一个;搜寻匹配单词signal、signaL、Signal、SignaL的行;grep -n ‘[Ss]igna[Ll]’ 1.txt |
| . | .匹配一个非换行符的字符;grep -n ‘e.e’ 1.txt可以匹配 eee,eae,eve,但是不匹配 ee,eaae; |
| * | 匹配零个或多个先前字符 |
| [^] | 匹配一个不在指定范围内的字符 |
\(..\) |
标记匹配字符 |
| \ | 锚定单词的开始 |
\< |
锚定单词的开头 |
\> |
锚定单词的结束 |
x\{m\} |
重复字符x,m次 |
x\{m,\} |
重复字符x,至少m次 |
x\{m,n\} |
重复字符x,至少m次,不多于n次 |
| \w | 匹配文字和数字字符,也就是[A-Za-z0-9] |
| \b | 单词锁定符 |
实例:
显示所有以“h”结尾的行
grep h$
匹配所有以“a”开头且以“e”结尾的,中间包含2个字符的单词
grep ‘<a…e>’
显示所有包含一个”y”或”h”字符的行
grep [yh]
显示不包含字母a~k 且后紧跟“pple”的单词
1 | grep [^a-k]pple |
从系统词典中选择所有以“c”开头且以“o”结尾的单词grep '\<c.*o\>'
找出一个文件中或者输出中找到包含*的行grep '\*'
显示所有包含每个字符串至少有20个连续字母的单词的行grep [a-Z]\{20,\}
sort - 排序
语法:
1 | sort [-fbMnrtuk] [file or stdin] |
参数说明:
- -f :忽略大小写的差异,例如 A 与 a 视为编码相同;
- -b :忽略最前面的空格符部分;
- -M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
- -n :使用『纯数字』进行排序(默认是以文字型态来排序的);
- -r :反向排序;
- -u :就是 uniq ,相同的数据中,仅出现一行代表;
- -t :分隔符,默认是用 [tab] 键来分隔;
- -k :以哪个区间 (field) 来进行排序
默认是以第一个字符升序排序:
1 | # cat /etc/passwd | sort |
以第3列排序:
1 | [root@www ~]# cat /etc/passwd | sort -t ':' -k 3 |
使用数字排序:
1 | cat /etc/passwd | sort -t ':' -k 3n |
倒序排序:
1 | cat /etc/passwd | sort -t ':' -k 3nr |
先以第六个域的第2个字符到第4个字符进行正向排序,再基于第一个域进行反向排序:
1 | cat /etc/passwd | sort -t ':' -k 6.2,6.4 -k 1r |
查看/etc/passwd有多少个shell:
方法对/etc/passwd的第七个域排序并去重,然后统计行数:
1 | [root@VM_0_9_centos ~]# cat /etc/passwd | sort -t':' -k 7 -u |
uniq - 去重
1 | 选项与参数: |
该命令用于排完序之后,对排序结果进行去重
1 | python@xxx:~$ last | cut -d ' ' -f 1 | sort | uniq |
排序文件,默认是去重:
1 | #cat words | sort |uniq |
排序之后删除了重复行,同时在行首位置输出该行重复的次数:
1 | #sort testfile | uniq -c |
仅显示存在重复的行,并在行首显示该行重复的次数:
1 | #sort testfile | uniq -dc |
仅显示不重复的行:
1 | sort testfile | uniq -u |
tee - 同时输出多个文件
从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
一般情况下用重定向实现,需要同时输出多个文件时可以使用该命令。
参数:
- -a或–append 附加到既有文件的后面,而非覆盖它.
将输出同时保存到多个文件中,同时将输出内容显示到控制台:
1 | python@xxx:~/test$ echo "hello world"|tee f1 f2 |
tr - 替换指定的字符
不指定参数时,即表示替换指定的字符为另一个字符,支持指定的字符集合。
参数说明:
- -d, –delete:删除指定的字符
- -s, –squeeze-repeats:缩减连续重复的字符成指定的单个字符
字符集合的范围:
- \NNN 八进制值的字符 NNN (1 to 3 为八进制值的字符)
- \ 反斜杠
- \a Ctrl-G 铃声
- \b Ctrl-H 退格符
- \f Ctrl-L 走行换页
- \n Ctrl-J 新行
- \r Ctrl-M 回车
- \t Ctrl-I tab键
- \v Ctrl-X 水平制表符
- CHAR1-CHAR2 :字符范围从 CHAR1 到 CHAR2 的指定,范围的指定以 ASCII 码的次序为基础,只能由小到大,不能由大到小。
- [CHAR*] :这是 SET2 专用的设定,功能是重复指定的字符到与 SET1 相同长度为止
- [CHAR*REPEAT] :这也是 SET2 专用的设定,功能是重复指定的字符到设定的 REPEAT 次数为止(REPEAT 的数字采 8 进位制计算,以 0 为开始)
- [:alnum:] :所有字母字符与数字
- [:alpha:] :所有字母字符
- [:blank:] :所有水平空格
- [:cntrl:] :所有控制字符
- [:digit:] :所有数字
- [:graph:] :所有可打印的字符(不包含空格符)
- [:lower:] :所有小写字母
- [:print:] :所有可打印的字符(包含空格符)
- [:punct:] :所有标点字符
- [:space:] :所有水平与垂直空格符
- [:upper:] :所有大写字母
- [:xdigit:] :所有 16 进位制的数字
- [=CHAR=] :所有符合指定的字符(等号里的 CHAR,代表你可自订的字符)
将文件testfile中的小写字母全部转换成大写字母:
1 | cat testfile |tr a-z A-Z |
缩减连续重复的字符成指定的单个字符:
1 | python@xxx:~/test$ cat t |
删除指定的字符:
1 | python@xxx:~/test$ cat t|tr -d 'dv' |
join - 文件按行连接
将两个文件中指定栏位相同的行连接起来。即按照两个文件中共同拥有的某一列,将对应的行拼接成一行。
注意:在使用join之前所处理的文件要事先经过排序。
1 | $ cat testfile_1 |
使用join命令,将两个文件连接:
1 | $ join testfile_1 testfile_2 #连接testfile_1、testfile_2中的内容 |
两个文件互换,输出结果的变化:
1 | $ join testfile_2 testfile_1 #改变文件顺序连接两个文件 |
参数:
- -a<1或2> 除了显示原来的输出内容之外,还显示指令文件中没有相同栏位的行。
- -e<字符串> 若[文件1]与[文件2]中找不到指定的栏位,则在输出中填入选项中的字符串。
- -i或–igore-case 比较栏位内容时,忽略大小写的差异。
- -o<格式> 按照指定的格式来显示结果。
- -t<字符> 使用栏位的分隔字符。
- -v<1或2> 跟-a相同,但是只显示文件中没有相同栏位的行。
- -1<栏位> 连接[文件1]指定的栏位。
- -2<栏位> 连接[文件2]指定的栏位。
paste-将多个文件对应行链接在一起
paste 指令会把每个文件以列对列的方式,一列列地加以合并。
语法:
1 | paste [-s][-d <间隔字符>][文件...] |
参数:
- -d<间隔字符>或–delimiters=<间隔字符> 用指定的间隔字符取代跳格字符。
- -s或–serial 串列进行而非平行处理。
- [文件…] 指定操作的文件路径
使用paste指令将文件”file”、“testfile”、”testfile1”进行合并,输入如下命令:
1 | $ cat file #file文件的内容 |
参数”-s”可以将一个文件中的多行数据合并为一行进行显示:
1 | $ paste -s file #合并指定文件的多行数据 |
如果将文件位置改为-,表示接收标准输入:
1 | $ cat file |paste testfile1 - |
split - 文件切割
split命令用于将一个文件分割成数个。
该指令将大文件分割成较小的文件,在默认情况下将按照每1000行切割成一个小文件。
语法:
1 | split [-bl] file prefix |
参数说明:
- -<行数> : 指定每多少行切成一个小文件
- -b<字节> : 指定每多少字节切成一个小文件
- -C<字节> : 与参数”-b”相似,但是在切 割时将尽量维持每行的完整性
- [输出文件名] : 设置切割后文件的前置文件名, split会自动在前置文件名后再加上编号
使用指令”split”将文件”README”每6行切割成一个文件,输入如下命令:
1 | $ split -6 README #将README文件每六行分割成一个文件 |
以上命令执行后,指令”split”会将原来的大文件”README”切割成多个以”x”开头的小文件。而在这些小文件中,每个文件都只有6行内容。
以大小切割:
1 | $ ls -lh disease.dmp |
xargs - 参数代换
不是所有的命令都支持管道,如ls,对于不支持管道的命令,可以通过xargs让其有管道命令的效果,如下所示:
1 | # find /sbin -perm +7000 | xargs ls -l |
如果没有xargs,ls -l的结果将不是前面find的标准输出,因为ls不支持管道命令。
xargs 用作替换工具,读取输入数据重新格式化后输出。
定义一个测试文件,内有多行文本数据:
1 | # cat test.txt |
多行输入单行输出:
1 | # cat test.txt | xargs |
-n 选项多行输出:
1 | # cat test.txt | xargs -n3 |
-d 选项可以自定义一个定界符:
1 | # echo "nameXnameXnameXname" | xargs -dX |
结合 -n 选项使用:
1 | # echo "nameXnameXnameXname" | xargs -dX -n2 |
读取 stdin,将格式化后的参数传递给命令:
1 | # cat sk.sh |
选项-I指定一个替换字符串 {},这个字符串在 xargs 扩展时会被替换掉。
复制所有图片文件到 /data/images 目录下:
1 | ls *.jpg | xargs -n1 -I {} cp {} /data/images |
选项-n 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。
xargs 结合 find 使用
用 rm 删除太多的文件时候,可能得到一个错误信息:/bin/rm Argument list too long. 用 xargs 去避免这个问题:
1 | find . -type f -name "*.log" -print0 | xargs -0 rm -f |
xargs -0 将 \0 作为定界符。
统计一个源代码目录中所有 php 文件的行数:
1 | find . -type f -name "*.php" -print0 | xargs -0 wc -l |
查找所有的 jpg 文件,并且压缩它们:
1 | find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz |
批量下载:
1 | # cat url-list.txt | xargs wget -c |
wget的-c选项表示断点续传。
linux命令练习
常用命令
1 | 1.进入到用户根目录 |
系统命令
1 | 1.查看主机名 |
用户和组
1 | 添加一个tom用户,设置它属于users组,并添加注释信息 |
权限
1 | 创建a.txt和b.txt文件,将他们设为其拥有者和所在组可写入,但其他以外的人则不可写入: |
帮助文档
1 | 1.内部命令:echo |
文件相关命令
1 | 1.进入到用户根目录 |
VIM
1 | i |
查找
1 | 1.查找可执行的命令: |
打包与压缩
1 | 1.gzip压缩 |
正则表达式
1 | 规则: |
输入输出重定向
1 | 1.新建一个文件 |
进程控制
1 | 1.查看用户最近登录情况 |
其他命令
远程文件复制:scp
scp 命令用于 Linux 之间复制文件和目录,scp是 secure copy 的缩写是linux系统下基于ssh登陆进行安全的远程文件拷贝命令。
scp 是加密的,rcp 是不加密的,scp 是 rcp 的加强版。
使用scp命令要确保使用的用户具有可读取远程服务器相应文件的权限,否则scp命令是无法起作用的。
从本地复制到远程命令格式:
1 | 复制文件 |
实例:
1 | scp /home/space/music/1.mp3 root@xiaoxiaoming.xyz:/home/root/others/music |
从远程复制到本地:
1 | scp root@xiaoxiaoming.xyz:/home/root/others/music /home/space/music/1.mp3 |
-P 参数来设置命令的端口号:
1 | #scp 命令使用端口号 4588 |
locate查找
locate命令会去保存文档和目录名称的数据库内,查找文件或目录。
一般情况我们只需要输入locate your_file_name 即可查找指定文件。
参数:
- -d或–database= 配置locate指令使用的数据库。locate指令预设的数据库位于/var/lib/mlocate目录里,文档名为mlocate.db。
查找passwd文件,输入以下命令:
1 | locate passwd |
locate与find的区别: find 是去硬盘找,locate 只在/var/lib/slocate资料库中找。
locate的速度比find快,它并不是真的查找,而是查数据库,一般文件数据库在/var/lib/mlocate/mlocate.db中,所以locate的查找并不是实时的,而是以数据库的更新为准,一般是系统自己维护,也可以手工升级数据库 ,命令为:
1 | updatedb |
which命令
which查找$PATH中设置命令及安装文件目录所在位置
1 | python@ubuntu:/var/lib/mlocate$ which locate |
echo
常见用法:
1 | python@ubuntu:~$ echo -e "hello\t\t world!" 解析转义字符 |
设置或显示环境变量:export
在 shell 中执行程序时,shell 会提供一组环境变量。export 可新增,修改或删除环境变量,供后续执行的程序使用。export 的效力仅限于该次登陆操作。
1 | export [-fnp][变量名称]=[变量设置值] |
参数说明:
- -f 代表[变量名称]中为函数名称。
- -n 删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。
- -p 列出所有的shell赋予程序的环境变量。
1 | # export MYENV=7 //定义环境变量并赋值 |
修改主机名&ip地址
显示主机名:hostname
临时修改:hostname xxx
永久修改
对于Ubuntu 系统
1 | vim /etc/hostname |
对于centos系统
1 | vim /etc/sysconfig/network |
在此配置文件中添加一条HOSTNAME=node1
针对centos7系统,可以使用如下命令
1 | hostnamectl set-hostname xxx |
一般需要重开shell甚至重启操作系统才能生效。
修改IP地址
ifconfig eth0 192.168.12.22(重启后无效)
1 | vim /etc/sysconfig/network-scripts/ifcfg-eth0 |
mount挂载
mount 挂载外部存储设备到文件系统中
1 | mkdir /mnt/cdrom 创建一个目录,用来挂载 |
将设备/dev/cdrom挂载到 挂载点 : /mnt/cdrom中
1 | umount /mnt/cdrom |
ssh免密登陆
假如 A 要登陆 B
在A上操作:
首先生成密钥对
1 | ssh-keygen (提示时,直接回车即可) |
再将A自己的公钥拷贝并追加到B的授权列表文件authorized_keys中
1 | ssh-copy-id B |
批量添加用户
与用户账号有关的系统文件
完成用户管理的工作本质都是对有关的系统文件进行修改,这些系统文件包括/etc/passwd, /etc/shadow, /etc/group等。
/etc/passwd记录用户的基本属性
它的内容类似下面的例子:
1 | # cat /etc/passwd |
/etc/passwd中一行记录对应着一个用户,每行记录又被冒号(:)分隔为7个字段,其格式和具体含义如下:
1 | 用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell |
用户名:
通常长度不超过8个字符,由大小写字母和/或数字组成,不能有冒号(😃。登录名中不能有冒号(😃,因为冒号在这里是分隔符。
为了兼容起见,登录名中最好不要包含点字符(.),并且不使用连字符(-)和加号(+)打头。
口令:
本身存放用户口令的加密串,但现在许多Linux 系统都使用了shadow技术,把真正的加密后的用户口令字存放到/etc/shadow文件中,而/etc/passwd文件的口令字段中只存放一个特殊的字符,例如“x”或者“*”。
用户标识号:
是一个整数,系统内部用它来标识用户。一般情况下它与用户名是一一对应的,如果几个用户名对应的用户标识号是一样的,系统内部将把它们视为同一个用户,但是它们可以有不同的口令、不同的主目录以及不同的登录Shell等。
通常用户标识号的取值范围是0~65 535。0是超级用户root的标识号,1~99由系统保留,作为管理账号,普通用户的标识号从100开始。
组标识号:
记录用户所属的用户组,对应着/etc/group文件中的一条记录。
注释性描述:
一段任意编写的注释,创建账户时可以通过useradd -c 用户名的-c参数指定。
主目录:
用户的起始工作目录,用户在登录到系统之后所处的目录。
登录Shell:
用户登录后,要启动一个进程,负责将用户的操作传给内核,这个进程是用户登录到系统后运行的命令解释器或某个特定的程序,即Shell。
Shell是用户与Linux系统之间的接口。Linux的Shell有许多种,每种都有不同的特点。常用的有sh(Bourne Shell), csh(C Shell), ksh(Korn Shell), tcsh(TENEX/TOPS-20 type C Shell), bash(Bourne Again Shell)等。
可以通过usermod的-s参数为用户指定某个Shell。如果useradd不通过-s参数指定shell,那么系统使用bash为默认的登录Shell,即这个字段的值为/bin/bash。
为用户的登录指定特定的Shell可以限制用户只能运行指定的应用程序,在该应用程序运行结束后,用户就自动退出了系统。不过大部分Linux系统要求只有在系统中登记过的shell才能出现在这个字段中。
伪用户(pseudo users)
这些用户的登陆shell为/usr/sbin/nologin,即不能登录。它们的存在主要是方便系统管理,满足相应的系统进程对文件属主的要求。
常见的伪用户如下所示:
1 | bin 拥有可执行的用户命令文件 |
还有许多标准的伪用户,例如:audit, cron, mail, usenet等,它们也都各自为相关的进程和文件所需要。
/etc/shadow
对安全性要求较高的Linux系统都把/etc/passwd文件中的口令字段保存在/etc/shadow文件中,超级用户才拥有该文件读权限。
/etc/shadow中的记录行与/etc/passwd中的一一对应,它由pwconv命令根据/etc/passwd中的数据自动产生
字段是:
1 | 登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志 |
- “登录名”是与/etc/passwd文件中的登录名相一致的用户账号
- “口令”字段存放的是加密后的用户口令字,长度为13个字符。如果为空,则对应用户没有口令,登录时不需要口令;如果含有不属于集合 { ./0-9A-Za-z }中的字符,则对应的用户不能登录。
- “最后一次修改时间”表示的是从某个时刻起,到用户最后一次修改口令时的天数。大部分linux系统的时间起点是1970年1月1日。
- “最小时间间隔”指的是两次修改口令之间所需的最小天数。
- “最大时间间隔”指的是口令保持有效的最大天数。
- “警告时间”字段表示的是从系统开始警告用户到用户密码正式失效之间的天数。
- “不活动时间”表示的是用户没有登录活动但账号仍能保持有效的最大天数。
- “失效时间”字段给出的是一个绝对的天数,如果使用了这个字段,那么就给出相应账号的生存期。期满后,该账号就不再是一个合法的账号,也就不能再用来登录了。
下面是/etc/shadow的一个例子:
1 | # cat /etc/shadow |
/etc/group记录用户组信息
每个用户都属于某个用户组;一个组中可以有多个用户,一个用户也可以属于不同的组。
当一个用户同时是多个组中的成员时,在/etc/passwd文件中记录的是用户所属的主组,也就是登录时所属的默认组,而其他组称为附加组。
用户要访问属于附加组的文件时,必须首先使用newgrp命令使自己成为所要访问的组中的成员。
用户组的所有信息都存放在/etc/group文件中,字段有:
1 | 组名:口令:组标识号:组内用户列表 |
- “组名”是用户组的名称,由字母或数字构成。与/etc/passwd中的登录名一样,组名不应重复。
- “口令”字段存放的是用户组加密后的口令字。一般Linux 系统的用户组都没有口令,即这个字段一般为空,或者是*。
- “组标识号”与用户标识号类似,也是一个整数,被系统内部用来标识组。
- “组内用户列表”是属于这个组的所有用户的列表,不同用户之间用逗号(,)分隔。这个用户组可能是用户的主组,也可能是附加组。
/etc/group文件的一个例子如下:
1 | root::0:root |
实操
先编辑一个文本用户文件
每一列按照/etc/passwd密码文件的格式书写,要注意每个用户的用户名、UID、宿主目录都不可以相同,其中密码栏可以留做空白或输入x号。一个范例文件user.txt内容如下:
1 | user001::601:100:user:/home/user001:/bin/bash |
执行/usr/sbin/newusers命令
需要root权限:
1 | # newusers < user.txt |
可以执行命令 vipw 或 vi /etc/passwd 检查 /etc/passwd 文件是否已经出现这些用户的数据,并且用户的宿主目录是否已经创建。
取消 shadow password 功能
将 /etc/shadow 产生的 shadow 密码解码,然后回写到 /etc/passwd 中,并将/etc/shadow的shadow密码栏删掉。这是为了方便下一步的密码转换工作,即先取消 shadow password 功能。
执行/usr/sbin/pwunconv命令:
1 | # pwunconv |
编辑每个用户的密码对照文件
格式为:
1 | 用户名:密码 |
实例文件 passwd.txt 内容如下:
1 | user001:123456 |
执行 /usr/sbin/chpasswd命令
需要root权限:
创建用户密码,chpasswd 会将经过 /usr/bin/passwd 命令编码过的密码写入 /etc/passwd 的密码栏。
1 | # chpasswd < passwd.txt |
将密码编码为 shadow password
执行命令 /usr/sbin/pwconv 将密码编码为 shadow password,并将结果写入 /etc/shadow。
1 | # pwconv |
这样就完成了大量用户的创建了,之后您可以到/home下检查这些用户宿主目录的权限设置是否都正确,并登录验证用户密码是否正确。
完整步骤
先准备好用户文件user和密码文件passwd
然后运行:
1 | newusers < user |
crontab的使用
crontab命令是cron table的简写,它是cron的配置文件,也可以叫它作业列表。
相关配置文件如下:
- /var/spool/cron/ 目录下存放的是每个用户包括root的crontab任务,每个任务以创建者的名字命名
- /etc/crontab 这个文件负责调度各种管理和维护任务。
- /etc/cron.d/ 这个目录用来存放任何要执行的crontab文件或脚本。
- 还可以把脚本放在/etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthly目录中,让它每小时/天/星期、月执行一次。
命令格式:
1 | crontab [ -u user ] { -l | -r | -e } |
crontab -e进入当前用户的工作表编辑,是常见的vim界面。每行是一条命令。
crontab的命令构成为 时间+动作,其时间有分、时、日、月、周五种,操作符有
- ***** 取值范围内的所有数字
- / 每过多少个数字
- - 从X到Z
- **,**散列数字
基本格式 :
1 | f1 f2 f3 f4 f5 command |

- 其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。command表示要执行的命令。
- 当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,以此类推
- 当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,以此类推
- 当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,以此类推
- 当 f1 为 a, b, c,… 时表示第 a, b, c,… 分钟要执行,f2 为 a, b, c,… 时表示第 a, b, c…个小时要执行,以此类推
在 12 月内, 每天的早上 6 点到 12 点,每隔 3 个小时 0 分钟执行一次 /usr/bin/backup
1 | 0 6-12/3 * 12 * /usr/bin/backup |
周一到周五每天下午 5:00 寄一封信给 alex@domain.name
1 | 0 17 * * 1-5 mail -s "hi" alex@domain.name < /tmp/maildata |
每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分…执行 echo “haha”
1 | 20 0-23/2 * * * echo "haha" |
示例1:
1 | 45 4 1,10,22 * * /etc/init.d/smb restart 每月1、10、22日的4 : 45重启smb |
示例2:
1 | 0 */2 * * * /sbin/service httpd restart 每两个小时重启一次apache |
环境变量问题:
有时创建了一个crontab,但是这个任务却无法自动执行,而手动执行这个任务却没有问题,这种情况一般是由于在crontab文件中没有配置环境变量引起的。
所以注意如下3点:
1)脚本中涉及文件路径时写全局路径;
2)脚本执行要用到java或其他环境变量时,通过source命令引入环境变量,如:
1 | cat start_cbp.sh |
3)当手动执行脚本OK,但是crontab死活不执行时,可以尝试在crontab中直接引入环境变量解决问题。如:
1 | 0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh |
特殊权限
linux共12位权限,除了9位基础权限还有3个特殊权限。
三种特殊的权限
SetUID(suid)
命令功能: **临时使用命令的属主权限执行该命令。**即如果文件有suid权限时,那么普通用户去执行该文件时,会以该文件的所属用户的身份去执行。
SetUID(简写suid):会在属主权限位的执行权限上写个s。 如果该属主权限位上有执行权限,则会在属主权限位的执行权限上写个s(小写); 如果该属主权限位上没有执行权限,则会在属主权限位的执行权限上写个S(大写)。
suid数字权限是4000,设置方法:
1 | 方式1: |
查看passwd命令的权限
1 | `[root@localhost ftl]``# ll /usr/bin/passwd ` `问题: ``passwd``文件的属组是root,表示只有root用户可以访问的文件,为什么普通用户依然可以使用该命令更改自己的密码?``答案:当普通用户[omd]使用``passwd``命令的时候,系统看到``passwd``命令文件的属性有大写s后,表示这个命令的属主权限被omd用户获得,也就是omd用户获得文件``/etc/shadow``的root的rwx权限` |
由于passwd具有s权限,普通用户使用该命令的时候,就会以该命令的属主身份root执行该命令,于是能够顺利修改普通用户不具备修改权限的/etc/shadow文件。
希望普通用户user1可以删除某个自己没有权限删除的文件的操作方法:
- sudo给user1授权rm权限
- rm设置suid
- 修改被删除文件上级目录的权限
SetUID(简称suid)总结:
- 让普通用户对可执行的二进制文件,临时拥有二进制文件的属主权限;
- 如果设置的二进制文件没有执行权限,那么suid的权限显示就是S(大写字母S);
- 特殊权限suid仅对二进制可执行程序有效,其他文件或目录则无效。
- suid极其危险,如果给vim或者rm命令设置了setUID,那么任何文件都能编辑或者删除了,相当于有root权限了。
setGID(sgid)
**命令功能:**使用sgid可以使得多个用户之间共享一个目录的所有文件变得简单。当某个目录设置了sgid后,在该目录中新建的文件不在是创建该文件的默认所属组。
如果该属组权限位上有执行权限,则会在属组主权限位的执行权限上写个s(小写字母); 如果该属组权限位上没有执行权限,则会在属组主权限位的执行权限上写个S(大写字母S)。
write命令的权限:
1 | [root@VM_0_9_centos ~]# ll /bin/write |
sgid数字权限是2000,设置方法:
1 | 方式1: |
在设置SetGID的文件夹创建文件的属组是父目录的属组:
1 | [root@VM_0_9_centos ~]# cd test/ |
sticky(sbit)粘滞位
**命令功能:**粘滞位,只对目录有效,对某目录设置粘滞位后,普通用户就算有w权限也只能删除该目录下自己建立的文件,而不能删除其他用户建立的文件。
如果该其他用户权限位上有执行权限,则会在其他用户权限位的执行权限上写个t(小写); 如果该其它用户权限位上没有执行权限,则会在其他用户权限位的执行权限上写个T(大写)。
系统中存在的/tmp目录是经典的粘滞位目录,谁都有写权限,因此安全成问题,常常是木马第一手跳板。
1 | [aaa@VM_0_9_centos ~]$ ll -d /tmp/ |
sbit数字权限是1000,设置方法:
1 | 方法1: |
chattr权限
chattr概述:凌驾于r、w、x、suid、sgid之上的权限。
lsattr:查看特殊权限
1 | [root@VM_0_9_centos ~]# lsattr /etc/passwd |
chattr:设置特殊权限
| 权限说明 | |
|---|---|
| -i | 锁定文件,不能编辑,不能修改,不能删除,不能移动,可以执行 |
| -a | 仅可以追加文件,不能编辑,不能删除,不能移动,可以执行 |
防止系统中某个关键文件被修改:
1 | [root@VM_0_9_centos ~]# chattr +i /etc/fstab |
让某个文件只能往里面追加内容,不能删除,一些日志文件适用于这种操作:
1 | [root@VM_0_9_centos ~]# chattr +a user_act.log |
掩码umask
umask的作用
umask值用于设置用户在创建文件时的默认权限,当我们在系统中创建目录或文件时,目录或文件所具有的默认权限就是由umask值决定的。
对于root用户,系统默认的umask值是0022;对于普通用户,系统默认的umask值是0002。执行umask命令可以查看当前用户的umask值。
1 | [root@VM_0_9_centos ~]# umask |
umask是如何改变新文件的权限
umask值一共有4组数字,其中第1组数字用于定义特殊权限,一般不予考虑,与一般权限有关的是后3组数字。
默认情况下,对于目录,用户所能拥有的最大权限是777;对于文件,用户所能拥有的最大权限是目录的最大权限去掉执行权限,即666。因为x执行权限对于目录是必须的,没有执行权限就无法进入目录,而对于文件则不必默认赋予x执行权限。
对于root用户,他的umask值是022。当root用户创建目录时,默认的权限就是用最大权限777去掉相应位置的umask值权限,即对于所有者不必去掉任何权限,对于所属组要去掉w权限,对于其他用户也要去掉w权限,所以目录的默认权限就是755;当root用户创建文件时,默认的权限则是用最大权限666去掉相应位置的umask值,即文件的默认权限是644。
通过umask命令可以修改umask值,比如将umask值设为0077。
1 | [root@VM_0_9_centos ~]# umask 0077 |
永久修改umask
umask命令只能临时修改umask值,系统重启之后umask将还原成默认值。如果要永久修改umask值,可修改/etc/bashrc或/etc/profile文件。
例如要将默认umask值设置为027,那么可以在文件中增加一行umask 027。
linux软件安装
Ubuntu软件安装与卸载
更新Ubuntu软件下载地址
开源软件镜像站 :https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/
Ubuntu 的软件源配置文件是 /etc/apt/sources.list。将系统自带的该文件做个备份,将该文件替换为下面内容,即可使用 TUNA 的软件源镜像。
ubuntu版本: 16.04 LTS
1 | # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 |
然后
1 | sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup |
再sudo vim /etc/apt/sources.list修改为以上内容
Ubuntu软件操作的相关命令
1 | sudo apt-get update 更新源 |
yum安装命令
yum( Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器。
基於RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载、安装。
yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。
更新国内yum源
网易(163)yum源是国内最好的yum源之一 ,无论是速度还是软件版本,都非常的不错。
将yum源设置为163 yum,可以提升软件包安装和更新的速度,同时避免一些常见软件版本无法找到。
首先备份/etc/yum.repos.d/CentOS-Base.repo
1 | mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup |
下载对应版本 repo 文件, 放入 /etc/yum.repos.d/
- CentOS5 :http://mirrors.163.com/.help/CentOS5-Base-163.repo
- CentOS6 :http://mirrors.163.com/.help/CentOS6-Base-163.repo
- CentOS7 :http://mirrors.163.com/.help/CentOS7-Base-163.repo
1 | wget http://mirrors.163.com/.help/CentOS7-Base-163.repo |
运行以下命令生成缓存
1 | yum clean all |
除了网易之外,国内还有其他不错的 yum 源,比如中科大和搜狐。
中科大的 yum 源,安装方法查看:https://lug.ustc.edu.cn/wiki/mirrors/help/centos
sohu 的 yum 源安装方法查看: http://mirrors.sohu.com/help/centos.html
yum常用命令
yum 语法:
1 | yum [options] [command] [package ...] |
选项:
- **options:**可选,选项包括-h(帮助),-y(当安装过程提示选择全部为”yes”),-q(不显示安装的过程)等等。
- **command:**要进行的操作。
- **package:**操作的对象。
实例:
- 列出所有可更新的软件清单命令:
yum check-update - 更新所有软件命令:
yum update - 仅安装指定的软件命令:
yum install <package_name> - 仅更新指定的软件命令:
yum update <package_name> - 显示包信息:
yum info <package_name> - 列出所有可安裝的软件清单命令:
yum list - 删除软件包命令:
yum remove <package_name> - 查找软件包 命令:
yum search <keyword> - 清除缓存命令:
- yum clean packages: 清除缓存目录下的软件包
- yum clean headers: 清除缓存目录下的 headers
- yum clean oldheaders: 清除缓存目录下旧的 headers
- yum clean, yum clean all (= yum clean packages; yum clean oldheaders) :清除缓存目录下的软件包及旧的headers
yum在线安装MySQL5.7
Step1: 检测系统是否自带安装mysql
1 | yum list installed | grep mysql |
Step2: 删除系统自带的mysql及其依赖
1 | yum -y remove mysql-libs.x86_64 |
Step3: 给CentOS添加rpm源,并且选择较新的源
1 | wget dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm |
Step4:安装mysql 服务器
1 | yum install mysql-community-server |
Step5: 启动mysql
1 | service mysqld start |
grep “password” /var/log/mysqld.log(查看临时密码)
1 | SET PASSWORD = PASSWORD('your new password'); |
默认的要求必须的设置格式:
包含数字、小写或大写字母以及特殊字符
默认的要求必须的设置格式:
包含数字、小写或大写字母以及特殊字符
如果不想复杂,可以使用以下方式
1 | set global validate_password_policy=0; |
Step6: 查看mysql是否自启动,并且设置开启自启动
1 | # chkconfig --list | grep mysqld |
Step7: mysql安全设置
1 | mysql_secure_installation |
rpm
RPM是Red Hat公司随Redhat Linux推出了一个软件包管理器,通过它能够更加轻松容易地实现软件的安装。
常见用法:
- rpm -ivh <rpm包名> 安装软件
- rpm -e <rpm包名> 卸载安装
- rpm -qi <rpm包名> 显示软件安装信息
- rpm -qa | grep xxx 查询软件是否安装(包括相关依赖)
- rpm -Uvh <rpm包名> 升级一个rpm
具体参数详解:
-i, –install 安装包
-v, –verbose 列出更多详细信息,安装进度
-h, –hash 安装时列出hash标记 (与 -v连用)
-e, –erase 卸载安装包
-U, –upgrade=+ 升级包
–replacepkge 无论软件包是否已被安装,都强行安装软件包
–test 安装测试,并不实际安装
–nodeps 忽略软件包的依赖关系强行安装
–force 忽略软件包及文件的冲突
-q,–query:
-a, –all 查询/校验所有的安装包
-p, –package 查询/校验一个安装文件
-l, –list 列出安装文件
-d, –docfiles 列出所有文档文件
-f, –file 查询/校验安装包中所包含的文件
安装软件:
1 | # rpm -hvi dejagnu-1.4.2-10.noarch.rpm |
显示软件安装信息:
1 | # rpm -qi dejagnu-1.4.2-10.noarch.rpm |
Linux的基本配置
1.修改主机名
1 | vi /etc/sysconfig/network |
2.修改ip地址
1 | vi /etc/sysconfig/network-scripts/ifcfg-eth0 |
3.修改ip地址和主机名的映射关系
1 | vi /etc/hosts |
4.关闭iptables并设置其开机启动/不启动
1 | service iptables stop |
安装JDK
1 | 1.上传jdk-7u45-linux-x64.tar.gz到Linux上 |
制作本地YUM源
上传CentOS-6.7-x86_64-bin-DVD1.iso到服务器
将CentOS-6.7-x86_64-bin-DVD1.iso镜像挂载到某个目录:
1 | mkdir /var/iso |
安装并启动Apache服务器:
1 | yum install -y httpd |
使用浏览器访问http://192.168.100.101(如果访问不通,检查防火墙是否开启了80端口或关闭防火墙)
将YUM源配置到httpd中:
1 | cp -r /var/iso/ /var/www/html/CentOS-6.7 |
在浏览器中访问http://192.168.100.101/CentOS-6.7/

配置使用YUM源:
备份原有的YUM源的配置文件
1 | cd /etc/yum.repos.d/ |
修改YUM源配置文件
1 | vi CentOS-Local.repo |
重建yum缓存
1 | #清除yum缓存文件,重新新建 |
rpm包生成yum源目录
如果已经下载好了rpm包,可以自行制作一个yum源(yum仓库)。将下载的rpm包上传到centos服务器上(比如/data/rpm目录下),然后进入存放rpm包的目录,执行以下命令:
1 | # cd /data/rpm |
这样,rpm包存放的目录就可以作为yum源目录使用。
如果提示找不到createrepo命令,可以使用yum install createrepo安装该程序。
Shell编程
这里说的Shell 脚本(shell script),是在Linux 环境下运行的脚本程序
Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
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)
- ……
Bash是大多数Linux 系统默认的 Shell,本文也仅关注Bash Shell。
在一般情况下,并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。
#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。
入门
运行Shell脚本
编写shell脚本:
1 | vi test.sh |
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo 命令用于向窗口输出文本。
运行 Shell 脚本有两种方法:
1、作为可执行程序
1 | chmod +x ./test.sh #使脚本具有执行权限 |
默认情况下,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样。
除非将当前目录.加入到PATH环境变量中,配置方法:
1 | sudo vi /etc/profile |
2、作为解释器参数
直接运行解释器,其参数就是 shell 脚本的文件名:
1 | /bin/sh test.sh |
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。
编写一个快捷创建shell脚本的命令
1 | #!/bin/bash |
将以上内容编写好之后保存为shell文件,然后执行
1 | chmod u+x shell |
echo命令
Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出。命令格式:
1 | echo string |
显示普通字符串:
1 | echo "It is a test" |
这里的双引号完全可以省略,以下命令与上面实例效果一致:
1 | echo It is a test |
显示转义字符:
1 | echo "\"It is a test\"" |
结果将是:
1 | "It is a test" |
同样,双引号也可以省略
read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
1 | #!/bin/sh |
以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:
1 | [root@www ~]# sh test.sh |
显示换行
1 | echo -e "OK! \n" # -e 开启转义 |
输出结果:
1 | OK! |
显示不换行
1 | #!/bin/sh |
输出结果:
1 | OK! It is a test |
printf 命令
printf 命令的语法:
1 | printf format-string [arguments...] |
参数说明:
- format-string: 为格式控制字符串
- arguments: 为参数列表。
实例如下:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | 姓名 性别 体重kg |
- %s %c %d %f都是格式替代符
- %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
- %-4.2f 指格式化为小数,其中.2指保留2位小数。
printf的转义序列:
| 序列 | 说明 |
|---|---|
| \a | 警告字符,通常为ASCII的BEL字符 |
| \b | 后退 |
| \c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
| \f | 换页(formfeed) |
| \n | 换行 |
| \r | 回车(Carriage return) |
| \t | 水平制表符 |
| \v | 垂直制表符 |
| \ | 一个字面上的反斜杠字符 |
| \ddd | 表示1到3位数八进制值的字符。仅在格式字符串中有效 |
| \0ddd | 表示1到3位的八进制值字符 |
例子:
1 | python@ubuntu:~/test$ printf "a string, no processing:<%s>\n" "A\nB" |
Shell 注释
以 # 开头的行就是注释,会被解释器忽略:
1 | #-------------------------------------------- |
多行注释还可以使用以下格式:
1 | :<<EOF |
EOF 也可以使用其他符号:
1 | :<<' |
Shell变量
定义变量
1 | your_name="taobao.com" |
变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
使用变量
在变量名前面加美元符号即可,如:
1 | your_name="qinjx" |
加花括号可以帮助解释器识别变量的边界,比如:
1 | for skill in Ada Coffe Action Java; do |
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
下面的例子尝试更改只读变量,结果报错:
1 | python@ubuntu:~/shell$ myUrl="http://www.google.com" |
删除变量
使用 unset 命令可以删除变量,但不能删除只读变量:
1 | #!/bin/sh |
变量类型
运行shell时,会同时存在三种变量:
- 1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
- 2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
- 3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
Shell 函数
shell中函数的定义格式如下:
1 | [ function ] funname [()] |
说明:
- 1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
- 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
示例:
1 | #!/bin/bash |
输出,类似下面:
1 | 这个函数会对输入的两个数字进行相加运算... |
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
带参数的函数示例:
1 | #!/bin/bash |
输出结果:
1 | 第一个参数为 1 ! |
当n>=10时,需要使用${n}来获取参数。
另外,还有几个特殊字符用来处理参数:
| 参数处理 | 说明 |
|---|---|
| $# | 传递到脚本的参数个数 |
| $* | 以一个单字符串显示所有向脚本传递的参数 |
| $$ | 脚本运行的当前进程ID号 |
| $! | 后台运行的最后一个进程的ID号 |
| $@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 |
| $- | 显示Shell使用的当前选项,与set命令功能相同。 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
文件包含
Shell 文件包含的语法格式如下:
1 | . filename # 注意点号(.)和文件名中间有一空格 |
实例
创建两个 shell 脚本文件。
test1.sh 代码如下:
1 | #!/bin/bash |
test2.sh 代码如下:
1 | #!/bin/bash |
接下来,我们为 test2.sh 添加可执行权限并执行:
1 | $ chmod +x test2.sh |
**注:**被包含的文件 test1.sh 不需要可执行权限。
shell数据类型
字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号:
1 | str='this is a string' |
单引号字符串的限制:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号:
1 | your_name='taobao' |
输出结果为:
1 | Hello, I know you are "taobao"! |
双引号的优点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
拼接字符串:
1 | your_name="taobao" |
输出结果为:
1 | hello, taobao ! hello, taobao ! |
获取字符串长度${#s}
1 | string="abcd" |
截取字符串${s:n1:n2}
以下实例从字符串第 2 个字符开始截取 4 个字符:
1 | string="taobao is a great site" |
查找字符出现的位置expr index
查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):
1 | string="taobao is a great site" |
注意: 以上脚本中 ` 是反引号,而不是单引号 ‘。
数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
数组元素的下标由 0 开始编号。
定义数组
在 Shell 中,用括号来表示数组,数组元素用”空格”符号分割开。定义数组的一般形式为:
1 | array_name=(value0 value1 value2 value3) |
或者
1 | array_name=( |
或单独定义数组的各个分量:
1 | array_name[0]=value0 |
可以不使用连续的下标,而且下标的范围没有限制。
读取数组
读取数组元素值的一般格式是:
1 | valuen=${array_name[n]} |
例子:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | $ chmod +x test.sh |
使用 @或* 符号可以获取数组中的所有元素,例如:
1 | echo ${array_name[@]} |
例子:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | $ chmod +x test.sh |
获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
1 | # 取得数组元素的个数 |
例子:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | $ chmod +x test.sh |
Shell传递参数
执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。
n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
$0 为执行的文件名
test.sh文件内容如下:
1 | vi test.sh |
运行结果:
1 | python@ubuntu:~/test$ sh test.sh 1 2 3 |
参数获取:
| 参数处理 | 说明 |
|---|---|
| $# | 传递到脚本的参数个数 |
$* |
传递的参数作为一个字符串显示 |
| $$ | 脚本运行的当前进程ID号 |
| $! | 后台运行的最后一个进程的ID号 |
$@ |
与$*相同,但是使用时加引号 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | python@ubuntu:~/test$ ./test.sh 1 2 3 |
$*与$@的区别:
- 只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则
$*等价于 “1 2 3”(传递了一个参数),而$@等价于 “1” “2” “3”(传递了三个参数)。
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | python@ubuntu:~/test$ sh test 1 2 3 |
Shell基本运算符
Shell 和其他编程语言一样,支持多种运算符,包括:
- 算数运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | 两数之和为 : 4 |
两点注意:
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。
- 完整的表达式要被
包含,这个字符是反引号在 Esc 键下边。
算术运算符
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
| 运算符 | 说明 | 举例 |
|---|---|---|
| + | 加法 | expr $a + $b 结果为 30。 |
| - | 减法 | expr $a - $b 结果为 -10。 |
| * | 乘法 | expr $a \* $b 结果为 200。 |
| / | 除法 | expr $b / $a 结果为 2。 |
| % | 取余 | expr $b % $a 结果为 0。 |
| = | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
| == | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
| != | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
算术运算符实例如下:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | a + b : 30 |
注意:
- 乘号(*)前边必须加反斜杠
\才能实现乘法运算; - if…then…fi 是条件语句,后续将会讲解。
- 在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 “*” 不需要转义符号
\。
1 | let varName=算术表达式 |
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
| 运算符 | 说明 | 举例 |
|---|---|---|
| -eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
| -ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
| -gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
| -lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
| -ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ]返回 false。 |
| -le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
关系运算符实例如下:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | 10 -eq 20: a 不等于 b |
布尔运算符
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
| 运算符 | 说明 | 举例 |
|---|---|---|
| ! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
| -o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
| -a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
布尔运算符实例如下:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | 10 != 20 : a 不等于 b |
逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
| 运算符 | 说明 | 举例 |
|---|---|---|
| && | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
| || | 逻辑的 OR | `[[ $a -lt 100 |
逻辑运算符实例如下:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | 返回 false |
字符串运算符
下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:
| 运算符 | 说明 | 举例 |
|---|---|---|
| = | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
| != | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
| -z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
| -n | 检测字符串长度是否为0,不为0返回 true。 | [ -n "$a" ] 返回 true。 |
| $ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
字符串运算符实例如下:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | abc = efg: a 不等于 b |
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
属性检测描述如下:
| 操作符 | 说明 | 举例 |
|---|---|---|
| -b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
| -c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
| -d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
| -f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
| -g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
| -k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
| -p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
| -u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
| -r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
| -w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
| -x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
| -s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
| -e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
其他检查符:
- -S: 判断某文件是否 socket。
- -L: 检测文件是否存在并且是一个符号链接。
变量 file 表示文件 /var/www/runoob/test.sh,它的大小为 100 字节,具有 rwx 权限。下面的代码,将检测该文件的各种属性:
1 | #!/bin/bash |
执行脚本,输出结果如下所示:
1 | 文件可读 |
test命令
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
数值测试
| 参数 | 说明 |
|---|---|
| -eq | 等于则为真 |
| -ne | 不等于则为真 |
| -gt | 大于则为真 |
| -ge | 大于等于则为真 |
| -lt | 小于则为真 |
| -le | 小于等于则为真 |
实例演示:
1 | num1=100 |
输出结果:
1 | 两个数相等! |
代码中的 [] 执行基本的算数运算,如:
1 | #!/bin/bash |
结果为:
1 | result 为: 11 |
字符串测试
| 参数 | 说明 |
|---|---|
| = | 等于则为真 |
| != | 不相等则为真 |
| -z 字符串 | 字符串的长度为零则为真 |
| -n 字符串 | 字符串的长度不为零则为真 |
实例演示:
1 | num1="ru1noob" |
输出结果:
1 | 两个字符串不相等! |
文件测试
| 参数 | 说明 |
|---|---|
| -e 文件名 | 如果文件存在则为真 |
| -r 文件名 | 如果文件存在且可读则为真 |
| -w 文件名 | 如果文件存在且可写则为真 |
| -x 文件名 | 如果文件存在且可执行则为真 |
| -s 文件名 | 如果文件存在且至少有一个字符则为真 |
| -d 文件名 | 如果文件存在且为目录则为真 |
| -f 文件名 | 如果文件存在且为普通文件则为真 |
| -c 文件名 | 如果文件存在且为字符型特殊文件则为真 |
| -b 文件名 | 如果文件存在且为块特殊文件则为真 |
实例演示:
1 | cd /bin |
输出结果:
1 | 文件已存在! |
另外,Shell还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:”!“最高,”-a”次之,”-o”最低。例如:
1 | cd /bin |
输出结果:
1 | 至少有一个文件存在! |
Shell 流程控制
if else判断语句
if 语句语法格式:
1 | if condition |
写成一行(适用于终端命令提示符):
1 | if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi |
if else 语法格式:
1 | if condition |
if else-if else 语法格式:
1 | if condition1 |
以下实例判断两个变量是否相等:
1 | a=10 |
输出结果:
1 | a 小于 b |
if else语句经常与test命令结合使用,如下所示:
1 | num1=$[2*3] |
输出结果:
1 | 两个数字相等! |
for循环
for循环一般格式为:
1 | for var in item1 item2 ... itemN |
写成一行:
1 | for var in item1 item2 ... itemN; do command1; command2… done; |
例如,顺序输出当前列表中的数字:
1 | for loop in 1 2 3 4 5 |
输出结果:
1 | The value is: 1 |
顺序输出字符串中的字符:
1 | for str in 'This is a string' |
输出结果:
1 | This is a string |
while循环
while循环格式为:
1 | while condition |
示例:
1 | #!/bin/bash |
运行脚本,输出:
1 | 1 |
while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按Ctrl-D结束循环。
1 | echo '按下 <CTRL-D> 退出' |
运行脚本,输出类似下面:
1 | 按下 <CTRL-D> 退出 |
无限循环
无限循环语法格式:
1 | while : |
或者
1 | while true |
或者
1 | for (( ; ; )) |
until 循环
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
until 语法格式:
1 | until condition |
condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。
以下实例我们使用 until 命令来输出 0 ~ 9 的数字:
1 | #!/bin/bash |
运行结果:
输出结果为:
1 | 0 |
case
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:
1 | case 值 in |
下面的脚本提示输入1到4,与每一种模式进行匹配:
1 | echo '输入 1 到 4 之间的数字:' |
输入不同的内容,会有不同的结果,例如:
1 | 输入 1 到 4 之间的数字: |
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。
break命令允许跳出所有循环(终止执行后面的所有循环)。
下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。
1 | #!/bin/bash |
执行以上代码,输出结果为:
1 | 输入 1 到 5 之间的数字:3 |
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
Shell输入/输出重定向
重定向命令列表如下:
| 命令 | 说明 |
|---|---|
| command > file | 将输出重定向到 file。 |
| command < file | 将输入重定向到 file。 |
| command >> file | 将输出以追加的方式重定向到 file。 |
| n > file | 将文件描述符为 n 的文件重定向到 file。 |
| n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
| n >& m | 将输出文件 m 和 n 合并。 |
| n <& m | 将输入文件 m 和 n 合并。 |
| << tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
输出重定向
重定向一般通过在命令间插入特定的符号来实现。特别的,这些符号的语法如下所示:
1 | command1 > file1 |
上面这个命令执行command1然后将输出的内容存入file1。
注意任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用>>操作符。
输出重定向会覆盖文件内容:
1 | $ echo "www.baidu.com" > users |
如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,例如:
1 | $ echo "www.baidu.com" >> users |
输入重定向
和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:
1 | command1 < file1 |
这样,本来需要从键盘获取输入的命令会转移到文件读取内容。
注意:输出重定向是大于号(>),输入重定向是小于号(<)。
统计 users 文件的行数,执行以下命令:
1 | python@ubuntu:~/test$ wc -l test |
也可以将输入重定向到 users 文件:
1 | python@ubuntu:~/test$ wc -l <test |
注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。
同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中:
1 | command1 < infile > outfile |
重定向深入讲解
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。
如果希望 stderr 重定向到 file,可以这样写:
1 | $ command 2 > file |
如果希望 stderr 追加到 file 文件末尾,可以这样写:
1 | $ command 2 >> file |
2 表示标准错误文件(stderr)。
如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
1 | $ command > file 2>&1 |
如果希望对 stdin 和 stdout 都重定向,可以这样写:
1 | $ command < file1 >file2 |
command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。
Here Document
Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
它的基本的形式如下:
1 | command << delimiter |
它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
注意:结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
在命令行中通过 wc -l 命令计算 Here Document 的行数:
1 | $ wc -l << EOF |
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
1 | $ command > /dev/null |
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到”禁止输出”的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
1 | $ command > /dev/null 2>&1 |
0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
实例
杨辉三角:
1 | #!/bin/bash |
sum()&max():
1 | #!/bin/bash |
99乘法表:
1 | #!/bin/bash |
文本编辑命令
cut命令
1 | 选项与参数: |
cut以行为单位,根据分隔符把行分成若干列,这样就可以指定选取哪些列了。
1 | cut -d '分隔字符' -f 选取的列数 |
只显示/etc/passwd的用户和shell:
1 | #cat /etc/passwd | cut -d ':' -f 1,7 |
sed命令
sed 可依照脚本的指令来处理、编辑文本文件。
Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。
语法:
1 | sed [-e<script>][-f<script文件>][文本文件] |
参数说明:
-e <script>以指定的script来处理输入的文本文件。-f<script文件>以指定的script文件来处理输入的文本文件。-n仅显示script处理后的结果,一般跟p动作搭配使用。-i使用处理后的结果修改文件。
动作说明:
- a:在指定行后面插入内容
- i:在指定行前面插入内容
- d:删除指定行
- c :替换指定行
- p :打印指定行的数据,通常需要跟
-n选项搭配使用 - s :替换指定字符,兼容vim的替换语法,例如 1,20s/old/new/g
元字符集
sed支持一般的正则表达式,下面是支持的正则语法:^行的开始 如:/^sed/匹配所有以sed开头的行。$行的结束 如:/sed$/匹配所有以sed结尾的行。.匹配一个非换行符的任意字符 如:/s.d/匹配s后接一个任意字符,然后是d。*匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。[]匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。[^]匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。\(..\)保存匹配的字符,如s/(love)able/\1rs,loveable被替换成lovers。&保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。\<单词的开始,如:/<love/匹配包含以love开头的单词的行。\>单词的结束,如/love>/匹配包含以love结尾的单词的行。x\+重复字符x,至少1次,如:/o\+/匹配至少有1个o的行。x\{m\}重复字符x,m次,如:/o\{5\}/匹配包含5个o的行。x\{m,\}重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。x\{m,n\}重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5-10个o的行。
a|i:在指定行位置添加行
1 | python@xxx:~/test$ cat testfile |
默认情况下-e参数可以省略:
1 | python@xxx:~/test$ cat testfile|sed '2a\newline' |






