Bootstrap

《Linux命令行与shell脚本编程》学习笔记

第一章、 初识Linux shell

1. Linux介绍

在这里插入图片描述
Linux系统的核心是内核,内核主要负责以下四种功能:

  • 系统内存管理
  • 软件程序管理
  • 硬件设备管理
  • 文件系统管理

2. GNU工具

核心GNU工具

GNU项目的主旨在于为Unix系统管理员设计出一套类似于Unix的环境。GNU coreutils软件包由三部分构成:

  • 用以处理文件的工具
  • 用以操作文本的工具
  • 用以管理进程的工具

shell

GNU/Linux shell是一种特殊的交互式工具。它为用户提供了启动程序、管理文件系统中的文件以及运行在Linux系统上的进程的途径。shell的核心是命令行提示符。

3. Linux 版本

核心 Linux 发行版

发 行 版 描 述
Slackware 最早的Linux发行版中的一员,在Linux极客中比较流行
Red Hat 主要用于Internet服务器的商业发行版
Fedora 从Red Hat分离出的家用发行版
Gentoo 为高级Linux用户设计的发行版,仅包含Linux源代码
openSUSE 用于商用和家用的发行版
Debian 在Linux专家和商用Linux产品中流行的发行版

特定用途的Linux发行版

发 行 版 描 述
CentOS 一款基于Red Hat企业版Linux源代码构建的免费发行版
Ubuntu 一款用于学校和家庭的免费发行版
PCLinuxOS 一款用于家庭和办公的免费发行版
Mint 一款用于家庭娱乐的免费发行版
dyne:bolic 一款用于音频和MIDI应用的免费发行版
Puppy Linux 一款适用于老旧PC的小型免费发行版

第二章、 走进shell

1. 浏览文件系统

Linux会在根驱动器上创建一些特别的目录,我们称之为挂载点(mount point)。挂载点是虚拟目录中用于分配额外存储设备的目录。

常见Linux目录名称

目 录 用 途
/ 虚拟目录的根目录。通常不会在这里存储文件
/bin 二进制目录,存放许多用户级的GNU工具
/boot 启动目录,存放启动文件
/dev 设备目录,Linux在这里创建设备节点
/etc 系统配置文件目录
/home 主目录,Linux在这里创建用户目录
/lib 库目录,存放系统和应用程序的库文件
/media 媒体目录,可移动媒体设备的常用挂载点
/mnt 挂载目录,另一个可移动媒体设备的常用挂载点
/opt 可选目录,常用于存放第三方软件包和数据文件
/proc 进程目录,存放现有硬件及当前进程的相关信息
/root root用户的主目录
/sbin 系统二进制目录,存放许多GNU管理员级工具
/run 运行目录,存放系统运作时的运行时数据
/srv 服务目录,存放本地服务的相关文件
/sys 系统目录,存放系统硬件信息的相关文件
/tmp 临时目录,可以在该目录中创建和删除临时工作文件
/usr 用户二进制目录,大量用户级的GNU工具和数据文件都存储在这里
/var 可变目录,用以存放经常变化的文件,比如日志文件

遍历目录

cd destination
cd命令可接受单个参数destination,用以指定想切换到的目录名。
destination参数可以用两种方式表示:

  • 一种是使用绝对文件路径
  • 另一种是使用相对文件路径
绝对路径

绝对文件路径总是以正斜线(/)作为起始,指明虚拟文件系统的根目录。
pwd命令可以显示出shell会话的当前目录,这个目录被称为当前工作目录。

相对文件路径

相对文件路径允许用户指定一个基于当前位置的目标文件路径。相对文件路径不以代表根目录的正斜线(/)开头,而是以目录名(如果用户准备切换到当前工作目录下的一个目录)或是一个特殊字符开始。
有两个特殊字符可用于相对文件路径中:

  • 单点符(.),表示当前目录;
  • 双点符(…),表示当前目录的父目录。

2.文件和目录列表

ls命令最基本的形式会显示当前目录下的文件和目录,

ls相关的参数命令

参数 作用
-F 轻松区分文件和目录
-a 把隐藏文件和普通文件及目录一起显示出来
-R 列出了当前目录下包含的子目录中的文件
-l 产生长列表格式的输出,包含了目录中每个文件的更多相关信息
-i 查看文件或目录的inode编号

ls -l参数的文件内容

每一行都包含了关于文件(或目录)的下述信息:

  • 文件类型,比如目录(d)、文件(-)、字符型文件(c)或块设备(b);
  • 文件的权限(参见第6章);
  • 文件的硬链接总数;
  • 文件属主的用户名;
  • 文件属组的组名;
  • 文件的大小(以字节为单位);
  • 文件的上次修改时间;
  • 文件名或目录名。

过滤输出列表

用过滤器来决定应该在输出中显示哪些文件
或目录。这个过滤器就是一个进行简单文本匹配的字符串。可以在要用的命令行参数之后添加这个过滤器:

$ ls -l my_script

ls命令能够识别标准通配符,并在过滤器中用它们进行模式匹配:

  • 问号(?)代表一个字符;
  • 星号(*)代表零个或多个字符。
  • 中括号([])表示一个字符位置并给出多个可能的选择
a或i
$ ls -l my_scr[ai]pt 
字母范围[a – i]。
$ ls -l f[a-i]ll

在过滤器中使用星号和问号被称为文件扩展匹配(file globbing),指的是使用通配符进行模式匹配的过程。通配符正式的名称叫作元字符通配符(metacharacter wildcards)。

3. 处理文件

3.1 创建文件

touch命令轻松创建空文件。

$ touch test_one

如果只想改变访问时间,可用-a参数。

$ touch -a test_one 
$ ls -l test_one 
-rw-rw-r-- 1 christine christine 0 May 21 14:35 test_one 
$ ls -l --time=atime test_one 
-rw-rw-r-- 1 christine christine 0 May 21 14:55 test_one 
$

只使用ls –l命令,并不会显示访问时间。这是因为默认显示的是修改时间。要想查看文件的访问时间,需要加入另外一个参数:- -time=atime。有了这个参数,就能够显示出已经更改过的文件访问时间。

3.2 复制文件

cp命令需要两个参数——源对象和目标对象:

  • 当source和destination参数都是文件名时,cp命令将源文件复制成一个新文件,并且以destination命名。
cp source destination
  • 如果目标文件已经存在,cp命令可能并不会提醒这一点。最好是加上-i选项,强制shell询问是否需要覆盖已有文件。
 cp -i test_one test_two 
  • 其中的单点符(.)就很适合用于cp命令。记住,单点符表示当前工作目录。如果需要将一个带有很长的源对象名的文件复制到当前工作目录中时,单点符能够简化该任务。
cp -i /etc/NetworkManager/NetworkManager.conf . 
  • cp命令的-R参数威力强大。可以用它在一条命令中递归地复制整个目录的内容。
cp -R 目标文件夹/ 新建的文件夹
  • 也可以在cp命令中使用通配符。该命令将所有以script结尾的文件复制到Mod_Scripts目录中。在这里,只需要复制一个文件:
    my_script。
cp *script Mod_Scripts/

3.3 链接文件

如需要在系统上维护同一文件的两份或多份副本,除了保存多份单独的物理文件副本之外,还可以采用保存一份物理文件副本和多个虚拟副本的方法。这种虚拟的副本就称为链接。链接是目录中指向文件真实位置的占位符。在Linux中有两种不同类型的文件链接:

  • 符号链接
  • 硬链接

要为一个文件创建符号链接,原始文件必须事先存在。然后可以使用ln命令以及-s选项来创建符号链接。

ln -s data_file sl_data_file

3.4 重命名文件

重命名文件称为移动(moving),mv命令可以将文件和目录移动到另一个位置或重新命名。

mv 旧文件名 新文件名

inode编号和时间戳保持不变。这是因为mv只影响文件名

  • 使用mv来移动文件的位置。
mv 旧文件名 文件夹/
  • 使用mv命令移动文件位置并修改文件名称,文件的时间戳和inode编号都没有改变,只改变位置和名称。
mv /home/christine/Pictures/fzll /home/christine/fall

3.5 删除文件

bash shell中删除文件的命令是rm。rm命令的基本格式非常简单。

rm -i fall
  • -i命令参数提示你是不是要真的删除该文件。bash shell中没有回收站或垃圾箱,文件一旦删除,就无法再找回。
  • rm命令的另外一个特性是,如果要删除很多文件且不受提示符的打扰,可以用-f参数强制删除。

4. 处理目录

4.1 创建目录

系统创建了一个名为New_Dir的新目录。

 mkdir New_Dir

想单单靠mkdir命令来实现,就会得到错误消息,要想同时创建多个目录和子目录,需要加入-p参数。-p参数可以根据需要创建缺失的父目录。父目录是包含目录树中下一级目录的目录。

 mkdir -p New_Dir/Sub_Dir/Under_Dir

4.2 删除目录

删除目录的基本命令是rmdir,rmdir命令只删除空目录。

rmdir New_Dir

要想删除非空目录,得先把目录中的文件删掉,在整个非空目录上使用rm命令。使用-r选项使得命令可以向下进入目录,删除其中的文件,然后再删除目录本身

rm -ri My_Dir 

5. 查看文件内容

5.1 查看文件类型

file my_file
#file命令不仅能确定文件中包含的文本信息,还能确定该文本文件的字符编码,ASCII;
#也能展示链接,甚至能够告诉你它链接到了哪个文件上
#还能展示了file命令对脚本文件的返回结果
#如果文件是个二进制可执行程序,file命令能够确定该程序编译时所面向的平台以及需要何种类型的库。

file New_Dir
#后可以使用file命令作为另一种区分目录的方法

5.2 查看整个文件

  • cat命令
cat test1 

cat -n test1 
#-n参数会给所有的行加上行号

cat -b test1 
#如果只想给有文本的行加上行号,可以用-b参数。

cat -T test1
#如果不想让制表符出现,可以用-T参数。
  • more命令
    more命令会显示文本文件的内容,但会在显示每页数据之后停下来,more命令只支持文本文件中的基本移动。
  • less命令
    less命令的操作和more命令基本一样,一次显示一屏的文件文本。除了支持和more命令相同的命令集,它还包括更多的选项。less命令能够识别上下键以及上下翻页键

5.3 查看部分文件

  • tail命令
    tail命令会显示文件最后几行的内容(文件的“尾部”)。默认情况下,它会显示文件的末尾10行。
tail log_file

#可以向tail命令中加入-n参数来修改所显示的行数。
tail -n 2 log_file 

#-f参数是tail命令的一个突出特性。它允许你在其他进程使用该文件时查看文件的内容。
  • head
    head命令,顾名思义,会显示文件开头那些行的内容。
head log_file 

#可以向head命令中加入-n参数来修改所显示的行数。
tail -2 log_file 

#head命令并像tail命令那样支持-f参数特性

第四章、 更多的bash shell命令

1. 监控程序

1.1 探查进程

ps命令能输出运行在系统上的所有程序的许多信息。ps命令只会显示运行在当前控制台下的属于当前用户的进程。

ps

Linux系统中使用的GNU ps命令支持3种不同类型的命令行参数:

  • Unix风格的参数,前面加单破折线;
  • BSD风格的参数,前面不加破折线;
  • GNU风格的长参数,前面加双破折线
1.1.1 Unix风格的ps命令参数
参 数 描 述
-A 显示所有进程
-N 显示与指定参数不符的所有进程
-a 显示除控制进程(session leader①)和无终端进程外的所有进程
-d 显示除控制进程外的所有进程
-e 显示所有进程
-C cmdlist 显示包含在cmdlist列表中的进程
-G grplist 显示组ID在grplist列表中的进程
-U userlist 显示属主的用户ID在userlist列表中的进程
-g grplist 显示会话或组ID在grplist列表中的进程②
-p pidlist 显示PID在pidlist列表中的进程
-s sesslist 显示会话ID在sesslist列表中的进程
-t ttylist 显示终端ID在ttylist列表中的进程
-u userlist 显示有效用户ID在userlist列表中的进程
-F 显示更多额外输出(相对-f参数而言)
-O format 显示默认的输出列以及format列表指定的特定列
-M 显示进程的安全信息
-c 显示进程的额外调度器信息
-f 显示完整格式的输出
-j 显示任务信息
-l 显示长列表
-o format 仅显示由format指定的列
-y 不要显示进程标记(process flag,表明进程状态的标记)
-Z 显示安全标签(security context)①信息
-H 用层级格式来显示进程(树状,用来显示父进程)
-n namelist 定义了WCHAN列显示的值
-w 采用宽输出模式,不限宽度显示
-L 显示进程中的线程
-V 显示ps命令的版本号

-f参数则扩展了输出,这些扩展的列包含了有用的信息。

  • UID:启动这些进程的用户。
  • PID:进程的进程ID。
  • PPID:父进程的进程号(如果该进程是由另一个进程启动的)。
  • C:进程生命周期中的CPU利用率。
  • STIME:进程启动时的系统时间。
  • TTY:进程启动时的终端设备。
  • TIME:运行进程需要的累计CPU时间。
  • CMD:启动的程序名称。
1.1.2 BSD风格的ps命令参数
参 数 描 述
T 显示跟当前终端关联的所有进程
a 显示跟任意终端关联的所有进程
g 显示所有的进程,包括控制进程
r 仅显示运行中的进程
x 显示所有的进程,甚至包括未分配任何终端的进程
U userlist 显示归userlist列表中某用户ID所有的进程
p pidlist 显示PID在pidlist列表中的进程
t ttylist 显示所关联的终端在ttylist列表中的进程
O format 除了默认输出的列之外,还输出由format指定的列
X 按过去的Linux i386寄存器格式显示
Z 将安全信息添加到输出中
j 显示任务信息
l 采用长模式
o format 仅显示由format指定的列
s 采用信号格式显示
u 采用基于用户的格式显示
v 采用虚拟内存格式显示
N namelist 定义在WCHAN列中使用的值
O order 定义显示信息列的顺序
S 将数值信息从子进程加到父进程上,比如CPU和内存的使用情况
c 显示真实的命令名称(用以启动进程的程序名称)
e 显示命令使用的环境变量
f 用分层格式来显示进程,表明哪些进程启动了哪些进程
h 不显示头信息
k sort 指定用以将输出排序的列
n 和WCHAN信息一起显示出来,用数值来表示用户ID和组ID
w 为较宽屏幕显示宽输出
H 将线程按进程来显示
m 在进程后显示线程
L 列出所有格式指定符
V 显示ps命令的版本号
1.1.3 GNU风格的ps命令参数
参 数 描 述
–deselect 显示所有进程,命令行中列出的进程
–Group grplist 显示组ID在grplist列表中的进程
–User userlist 显示用户ID在userlist列表中的进程
–group grplist 显示有效组ID在grplist列表中的进程
–pid pidlist 显示PID在pidlist列表中的进程
–ppid pidlist 显示父PID在pidlist列表中的进程
–sid sidlist 显示会话ID在sidlist列表中的进程
–tty ttylist 显示终端设备号在ttylist列表中的进程
–user userlist 显示有效用户ID在userlist列表中的进程
–format format 仅显示由format指定的列
–context 显示额外的安全信息
–cols n 将屏幕宽度设置为n列
–columns n 将屏幕宽度设置为n列
–cumulative 包含已停止的子进程的信息
–forest 用层级结构显示出进程和父进程之间的关系
–headers 在每页输出中都显示列的头
–no-headers 不显示列的头
–lines n 将屏幕高度设为n行
–rows n 将屏幕高度设为n排
–sort order 指定将输出按哪列排序
–width n 将屏幕宽度设为n列
–help 显示帮助信息
–info 显示调试信息
–version 显示ps命令的版本号

1.2 实时监测进程

top命令跟ps命令相似,能够显示进程信息,但它是实时显示的。
top命令的输出中将进程叫作任务(task):有多少进程处在运行、休眠、停止或是僵化状态(僵化状态是指进程完成了,但父进程没有响应)

1.3 结束进程

  1. kill命令
    kill命令可通过进程ID(PID)给进程发信号。默认情况下,kill命令会向命令行中列出的全部PID发送一个TERM信号。
  2. killall命令
    killall命令非常强大,它支持通过进程名而不是PID来结束进程。killall命令也支持通配符,这在系统因负载过大而变得很慢时很有用。

2. 监测磁盘空间

2.1 挂载存储媒体

Linux文件系统将所有的磁盘都并入一个虚拟目录下。在使用新的存储媒体之前,需要把它放到虚拟目录下。这项工作称为挂载(mounting)。

2.1.1 mount命令

Linux上用来挂载媒体的命令叫作mount。默认情况下,mount命令会输出当前系统上挂载的设备列表。
mount命令提供如下四部分信息:

  • 媒体的设备文件名
  • 媒体挂载到虚拟目录的挂载点
  • 文件系统类型
  • 已挂载媒体的访问状态
    mount命令的参数
参 数 描 述
-a 挂载/etc/fstab文件中指定的所有文件系统
-f 使mount命令模拟挂载设备,但并不真的挂载
-F 和-a参数一起使用时,会同时挂载所有文件系统
-v 详细模式,将会说明挂载设备的每一步
-I 不启用任何/sbin/mount.filesystem下的文件系统帮助文件
-l 给ext2、ext3或XFS文件系统自动添加文件系统标签
-n 挂载设备,但不注册到/etc/mtab已挂载设备文件中
-p num 进行加密挂载时,从文件描述符num中获得密码短语
-s 忽略该文件系统不支持的挂载选项
-r 将设备挂载为只读的
-w 将设备挂载为可读写的(默认参数)
-L label 将设备按指定的label挂载
-U uuid 将设备按指定的uuid挂载
-O 和-a参数一起使用,限制命令只作用到特定的一组文件系统上
-o 给文件系统添加特定的选项
2.1.2 umount命令

支持通过设备文件或者是挂载点来指定要卸载的设备。

umount [directory | device ] 

2.2 使用 df 命令

查看所有已挂载磁盘的使用情况。

$ df 
Filesystem 1K-blocks Used Available Use% Mounted on 
/dev/sda2 18251068 7703964 9605024 45% / 
/dev/sda1 101086 18680 77187 20% /boot 
tmpfs 119536 0 119536 0% /dev/shm 
/dev/sdb1 127462 113892 13570 90% /media/disk 
$ 

命令输出如下:
 设备的设备文件位置;
 能容纳多少个1024字节大小的块;
 已用了多少个1024字节大小的块;
 还有多少个1024字节大小的块可用;
 已用空间所占的比例;
 设备挂载到了哪个挂载点上

一个常用的参数是-h。它会把输出中的磁盘空间按照用户易读的形式显示,通常用M来替代兆字节,用G替代吉字节。

2.3 使用 du 命令

du命令可以显示某个特定目录(默认情况下是当前目录)的磁盘使用情况。

下面是能让du命令用起来更方便的几个命令行参数。
 -c:显示所有已列出文件总的大小。
 -h:按用户易读的格式输出大小,即用K替代千字节,用M替代兆字节,用G替代吉字节。
 -s:显示每个输出参数的总计。

3. 处理数据文件

3.1 排序数据

$ sort file1 

#上面的命令如果输出有数字还是按字符串排序,加上-n参数以后数字信息就会按数字排序
$ sort -n file2 

#将含有时间戳日期的文件按默认的排序方法来排序
$ sort -M file3 

sort命令参数

单破折线 双破折线 描 述
-b –ignore-leading-blanks 排序时忽略起始的空白
-C –check=quiet 不排序,如果数据无序也不要报告
-c –check 不排序,但检查输入数据是不是已排序;未排序的话,报告
-d –dictionary-order 仅考虑空白和字母,不考虑特殊字符
-f –ignore-case 默认情况下,会将大写字母排在前面;这个参数会忽略大小写
-g –general-number-sort 按通用数值来排序(跟-n不同,把值当浮点数来排序,支持科学计数法表示的值)
-i –ignore-nonprinting 在排序时忽略不可打印字符
-k –key=POS1[,POS2] 排序从POS1位置开始;如果指定了POS2的话,到POS2位置结束
-M –month-sort 用三字符月份名按月份排序
-m –merge 将两个已排序数据文件合并
-n –numeric-sort 按字符串数值来排序(并不转换为浮点数)
-o –output=file 将排序结果写出到指定的文件中
-R –random-sort 按随机生成的散列表的键值排序
–random-source=FILE 指定-R参数用到的随机字节的源文件
-r –reverse 反序排序(升序变成降序)
-S –buffer-size=SIZE 指定使用的内存大小
-s –stable 禁用最后重排序比较
-T –temporary-directory=DIR 指定一个位置来存储临时工作文件
-t –field-separator=SEP 指定一个用来区分键位置的字符
-u –unique 和-c参数一起使用时,检查严格排序;不和-c参数一起用时,仅输出第一例相似的两行
-z –zero-terminated 用NULL字符作为行尾,而不是用换行符

3.2 搜索数据

#grep命令行格式如下
grep [options] pattern [file]

#实例
$ grep t file1 
two 
three 

#进行反向搜索(输出不匹配该模式的行),可加-v参数。
$ grep -v t file1 

#显示匹配模式的行所在的行号,可加-n参数。
$ grep -n t file1 

#只要知道有多少行含有匹配的模式,可用-c参数。
$ grep -c t file1 

#要指定多个匹配模式,可用-e参数来指定每个模式。
$ grep -e t -e f file1 

3.3 压缩数据

Linux文件压缩工具

工 具 文件扩展名 描 述
bzip2 .bz2 采用Burrows-Wheeler块排序文本压缩算法和霍夫曼编码
compress .Z 最初的Unix文件压缩工具,已经快没人用了
gzip .gz GNU压缩工具,用Lempel-Ziv编码
zip .zip Windows上PKZIP工具的Unix实现

3.4 归档数据

tar命令最开始是用来将文件写到磁带设备上归档的,然而它也能把输出写到文件里。

tar命令语法

tar function [options] object1 object2 ... 

tar命令的功能

功 能 长 名 称 描 述
-A –concatenate 将一个已有tar归档文件追加到另一个已有tar归档文件
-c –create 创建一个新的tar归档文件
-d –diff 检查归档文件和文件系统的不同之处
–delete 从已有tar归档文件中删除
-r –append 追加文件到已有tar归档文件末尾
-t –list 列出已有tar归档文件的内容
-u –update 将比tar归档文件中已有的同名文件新的文件追加到该tar归档文件中
-x –extract 从已有tar归档文件中提取文件

tar命令选项

选 项 描 述
-C dir 切换到指定目录
-f file 输出结果到文件或设备file
-j 将输出重定向给bzip2命令来压缩内容
-p 保留所有文件权限
-v 在处理文件时显示文件
-z 将输出重定向给gzip命令来压缩内容

示例代码:

#来创建一个归档文件:
tar -cvf test.tar test/ test2/

第五章、 理解shell

1. shell 的类型

用户christine使用GNU bash shell作为自己的默认shell程序。

bash shell程序位于/bin目录内。从长列表中可以看出/bin/bash(bash shell)是一个可执行程序。

用户christine默认的交互shell是/bin/bash,也就是bash shell。

并不是必须一直使用默认的交互shell。可以使用发行版中所有可用的shell,只需要输入对应的文件名就行了。例如,你可以直接输入命令/bin/dash来启动dash shell。

除启动了dash shell程序之外,看起来似乎什么都没有发生。提示符$是dash shell的CLI提示符。可以输入exit来退出dash shell。

2. shell 的父子关系

在CLI提示符后输入/bin/bash命令或其他等效的bash命令时,会创建一个新的shell程序。这个shell程序被称为子shell(child shell)。子shell也拥有CLI提示符,同样会等待命令输入。

2.1 进程列表

可以在一行中指定要依次运行的一系列命令。这可以通过命令列表来实现,只需要在命令之间加入分号(;)即可。

$ pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls

如果该命令返回0,就表明没有子shell。如果返回1或者其他更大的数字,就表明存在子shell。

2.2 别出心裁的子 shell 用法

2.2.1 探索后台模式

sleep命令接受一个参数,该参数是你希望进程等待(睡眠)的秒数。这个命令在脚本中常用于引入一段时间的暂停。

#命令sleep 10会将会话暂停10秒钟,然后返回shell CLI提示符。
$ sleep 10 

可以使用jobs命令来显示后台作业信息。jobs命令可以显示出当前运行在后台模式中的所有用户的进程(作业)。

$ jobs 
[1]+ Running sleep 3000 &
#除了默认信息之外,-l选项还能够显示出命令的PID。
jobs -l 
[1]+ 2396 Running sleep 3000 & 
2.2.2 将进程列表置入后台

将进程列表置入后台模式并不是子shell在CLI中仅有的创造性用法。协程就是另一种方法。

2.2.3 协程

协程可以同时做两件事。它在后台生成一个子shell,并在这个子shell中执行命令。
要进行协程处理,得使用coproc命令,还有要在子shell中执行的命令。

$ coproc sleep 10 
[1] 2544 

在命令行中使用子shell能够获得灵活性和便利。要想获得这些优势,重要的是理解子shell的行为方式。对

2.3 理解 shell 的内建命令

2.3.1 外部命令

外部命令程序通常位于/bin、/usr/bin、/sbin或/usr/sbin中。
可以使用which和type命令找到它。

$ which ps 
/bin/ps 
$ 
$ type -a ps 
ps is /bin/ps 

当进程必须执行衍生操作时,它需要花费时间和精力来设置新子进程的环境。所以说,外部命令多少还是有代价的。

2.3.2 内建命令

内建命令和外部命令的区别在于前者不需要使用子进程来执行。

  • 使用history命令
    要查看最近用过的命令列表,可以输入不带选项的history命令。

可以在退出shell会话之前强制将命令历史记录写入.bash_history文件。要实现强制写入,需要使用history命令的-a选项。

$ history -a

命令别名
alias命令是另一个shell的内建命令。命令别名允许你为常用的命令(及其参数)创建另一个名称,从而将输入量减少到最低。使用alias命令以及选项-p。

$ alias -p 

第六章 使用Linux环境变量

1. 什么是环境变量

bash shell用一个叫作环境变量(environment variable)的特性来存储有关shell会话和工作环境的信息(这也是它们被称作环境变量的原因)。
在bash shell中,环境变量分为两类:
 全局变量
 局部变量

1.1 全局环境变量

全局环境变量对于shell会话和所有生成的子shell都是可见的。

系统环境变量基本上都是使用全大写字母,以区别于普通用户的环境变量。

要查看全局变量,可以使用env或printenv命令。

$ printenv HOME 
/home/Christine 
$ 
$ env HOME 
env: HOME: No such file or directory
$ echo $HOME 
/home/Christine 

1.2 局部环境变量

局部环境变量只能在定义它们的进程中可见。
在Linux系统并没有一个只显示局部环境变量的命令。set命令会显示为某个特定进程设置的所有环境变量,包括局部变量、全局变量以及用户定义变量。

2. 设置用户定义变量

2.1 设置局部用户定义变量

一旦启动了bash shell(或者执行一个shell脚本),就能创建在这个shell进程内可见的局部变量了。可以通过等号给环境变量赋值,值可以是数值或字符串。

$ echo $my_variable 
$ my_variable=Hello 
$ 
$ echo $my_variable 

注意

  • 所有的环境变量名均使用大写字母,这是bash shell的标准惯例。如果是你自己创建的局部变量或是shell脚本,请使用小写字母。变量名区分大小写。
  • 变量名、等号和值之间没有空格,这一点非常重要。如果在赋值表达式中加上了空格,bash shell就会把值当成一个单独的命令。
  • 设置了局部环境变量后,就能在shell进程的任何地方使用它了。但是,如果生成了另外一个shell,它在子shell中就不可用。

2.2 设置全局环境变量

在设定全局环境变量的进程所创建的子进程中,该变量都是可见的。创建全局环境变量的方法是先创建一个局部环境变量,然后再把它导出到全局环境中。
通过export命令来完成,变量名前面不需要加$。

$ my_variable="I am Global now" 
$ export my_variable 
$ 
$ echo $my_variable 
I am Global now 
$ 
$ bash 
$ 
$ echo $my_variable 
I am Global now 
$ 
$ my_variable="Null" 
$ 
$ echo $my_variable 
Null

3. 删除环境变量

可以用unset命令完成这个操作。

$ echo $my_variable 
I am Global now 
$ 
$ unset my_variable 
$ 
$ echo $my_variable 

4. 默认的 shell 环境变量

默认情况下,bash shell会用一些特定的环境变量来定义系统环境。

bash shell支持的Bourne变量

变 量 描 述
CDPATH 冒号分隔的目录列表,作为cd命令的搜索路径
HOME 当前用户的主目录
IFS shell用来将文本字符串分割成字段的一系列字符
MAIL 当前用户收件箱的文件名(bash shell会检查这个文件,看看有没有新邮件)
MAILPATH 冒号分隔的当前用户收件箱的文件名列表(bash shell会检查列表中的每个文件,看看有没有新邮件)
OPTARG getopts命令处理的最后一个选项参数值
OPTIND getopts命令处理的最后一个选项参数的索引号
PATH shell查找命令的目录列表,由冒号分隔
PS1 shell命令行界面的主提示符
PS2 shell命令行界面的次提示符

除了默认的Bourne的环境变量,bash shell还提供一些自有的变量

5. 设置 PATH 环境变量

当你在shell命令行界面中输入一个外部命令时(参见第5章),shell必须搜索系统来找到对应的程序。PATH环境变量定义了用于进行命令和程序查找的目录。

$ echo $PATH

PATH中的目录使用冒号分隔。
可以把新的搜索目录添加到现有的PATH环境变量中,无需从头定义。

$ echo $PATH 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin: /sbin:/bin:/usr/games:/usr/local/games 
$ 
$ PATH=$PATH:/home/christine/Scripts 
$ 
$ echo $PATH 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/christine/Scripts 

注意:如果希望子shell也能找到你的程序的

;