Shell的作用及种类:

  • Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。
    实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。Shell编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。

  • 主要有下列版本的Shell:
    Bourne Shell:是贝尔实验室开发的。
    BASH:是GNU的Bourne Again Shell,是GNU操作系统上默认的shell。
    Korn Shell:是对Bourne SHell的发展,在大部分内容上与Bourne Shell兼容。
    C Shell:是SUN公司Shell的BSD版本。
    Z Shell:The last shell you’ll ever need! Z是最后一个字母,也就是终极Shell。它集成了bash、ksh的重要特性,同时又增加了自己独有的特性。


Bash的背景:

  • Bash是大多数Linux系统以及Mac OS X默认的Shell,它能运行于大多数类Unix风格的操作系统之上,甚至被移植到了Microsoft Windows上的Cygwin系统中,以实现Windows的POSIX虚拟接口。此外,它也被DJGPP项目移植到了MS-DOS上。

  • Bash的命令语法是Bourne Shell命令语法的超集。数量庞大的Bourne Shell脚本大多不经修改即可以在bash中执行,只用了Bourne特殊变量或使用了Bourne的内置命令的脚本才需要修改。 Bash的命令语法很多来自Korn Shell (ksh) 和 C Shell (csh), 例如命令行编辑,命令历史,目录栈,$RANDOM 和 $PPID 变量,以及POSIX的命令置换语法: $(…)。作为一个交互式的Shell,按下TAB键即可自动补全已部分输入的程序名,文件名,变量名等等。



Bash的基础特性:

1、命令历史

查看命令历史的命令:history

history #:显示历史中最近的#条命令

history -c:清空命令历史

history -d OFFSET[n]:删除指定位置的命令

history -w:保存命令历史至历史文件中

history -a:手动追加当前会话缓冲区的命令历史至历史文件中环境变量:

HISTSIZE:命令历史记录的条数

HISTFILESIZE:命令历史文件记录历史的条数

HISTFILE:命令历史纪录的位置,~/.bash_history

HISTCONTROL:命令历史纪录的纪录方式

export HISTCONTROL=ignoredups:忽略重复的命令,连续且相同方为“重复”

export HISTCONTROL=ignorespace:忽略所有以空白开头的命令

export HISTCONTROL=ignoreboth:ignoredups, ignorespace同时生效;

Note:修改环境变量值的方式:export 变量名=“值”

调用历史中的命令:

!#: 重复执行第#条命令

!!:重复执行最后一条执行的命令

!string:重复执行string为开头的命令

调用上一条命令的最后一个参数:

!$:作为参数传入上一条命令的最后一个参数,如:rm !$

ESC, .:先按ESC键,然后按.键,自动补充上一条命令的最后一个参数

Alt+.:按住Alt键,再按.键,自动补充上一条命令的最后一个参数

 

2、命令补全

直接补全:使用Tab键,用户给定的字符串只有一条惟一对应的命令

以用户给定的字符串为开头对应的命令不惟一,则再次Tab会给出列表

 

bash执行命令分为内部命令和外部命令(可执行文件:分成二进制和脚本两类):

(1)内部命令:常见的内建命令有echo,cd,trap等等。内建命令也分成两类:一类是某些外部可执行文件的同功能替代,目的是提高效率,如echo;第二类是其功能无法通过执行外部文件完成的必备命令,如cd。

(2)外部命令:bash根据PATH环境变量定义的路径,自左而右在每个路径搜寻以给定命令名命名的文件,第一次找到即为要执行的命令

Note:区别内部或外部命令:# type COMMAND

 

3、路径补全

给出的字符串当做路径开头,并在其指定的上级目录下搜索以指定的字符串开头的文件名或路径名:

如果惟一:则直接补全

否则:再次Tab,给出列表

 

4、命令行展开

~: 展开为用户的主目录

~USERNAME:展开为指定用户的主目录

{}:可承载一个以逗号分隔的列表,并将其展开为多个路径

/tmp/{a,b} = /tmp/a, /tmp/b

/tmp/{tom,jerry}/hi = /tmp/tom/hi, /tmp/jerry/hicd -:当前路径与上一次的路径相互切换

 

5、命令的执行结果状态

结果状态:成功、失败

bash使用特殊变量$?保存最近一条命令的执行状态结果:

0:成功

1-255:失败

程序执行有两类结果:

(1)程序的返回值

(2)程序的执行状态结果

 

6、命令别名(alias)

通过alias命令实现:

(1) alias:显示当前shell进程所有可用的命令别名

(2) alias NAME='VALUE':定义别名NAME,其相当于执行命令VALUE

 

Note:在命令行中定义的别名,仅对当前shell进程有效;

如果想永久有效,要定义在配置文件中:

仅对当前用户:~/.bashrc

对所有用户有效:/etc/bashrc

 

Note: 编辑配置给出的新配置不会立即生效

bash进程重新读取配置文件:

source /path/to/config_file

. /path/to/config_file

 

撤消别名:unalias

unalias [-a] name [name …]

 

Note: 如果别名与原命令的名称相同,要执行原命令,可使用"\COMMAND"

 

7、glob (globbing)

bash中用于实现文件名“通配”

*:任意长度的任意字符

 ?:任意单个字符

 []:匹配指定范围内的任意单个字符

[0-9]:匹配0-9的数字

[a-z]:不区分字符大小写

 [^]:匹配指定范围外的任意单个字符

[^0-9]

专用字符集合:

[:digit:]:任意数字,相当于0-9

[:lower:]:任意小写字母

[:upper:]: 任意大写字母

[:alpha:]: 任意大小写字母

[:alnum:]:任意数字或字母

[:space:]:任意空白字符

[:punct:]:任意标点符号

 

8、bash的快捷键

Ctrl+l: 清屏,相当于clear命令

Ctrl+a:跳转至命令开始处

Ctrl+e:跳转至命令结尾处

Ctrl+c:取消命令的执行

Ctrl+u: 删除命令行首至光村所在处的所有内容

Ctrl+k: 删除光标所在处至命令行尾部的所有内容

 

9、bash的的I/O重定向及管道

标准输入:keyborad, 0

标准输出:monitor, 1

标准错误输出:monitor, 2

 

I/O重定向:改变标准位置

输出重定向:COMMAND > NEW_POS, COMMAND >> NEW_POS

>:覆盖重定向,目标文件中的原有内容会被清除;

>>: 追加重定向,新内容会追加至目标文件尾部;

 

# set -C: 禁止将内容覆盖输出至已有文件中 ,强制覆盖:>|

# set +C: 允许将内容覆盖输出至已有文件中

 

2>: 覆盖重定向错误输出数据流;

2>>: 追加重定向错误输出数据流;

 

标准输出和错误输出各自定向至不同位置:

COMMAND > /path/to/file.out 2> /path/to/error.out

 

合并标准输出和错误输出为同一个数据流进行重定向:

&>:覆盖重定向

&>>:追加重定向

COMMAND > /path/to/file.out 2> &1

COMMAND >> /path/to/file.out 2>> &1

 

输入重定向:<

tr命令:转换或删除字符,tr [OPTION]… SET1 [SET2]

 

HERE Documentation:<<

# cat << EOF

# cat > /path/to/somefile << EOF

 

管道: COMMAND1 | COMMAND2 | COMMAND3 |…

Note:最后一个命令会在当前shell进程的子shell进程中执行

 

10、变量

主要分为本地变量、局部变量、环境变量、位置变量、特殊变量。

本地变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效

局部变量:生效范围为当前shell进程中某代码片断(通常指函数);

环境变量:生效范围为当前shell进程及其子进程;

位置变量:$1, $2, …来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数

特殊变量:$?, $0, $*, $@, $#

 

本地变量:

变量赋值:name='value'

(1) 可以是直接字串:name="username"

(2) 变量引用:name="$username"

(3) 命令引用:name=`COMMAND`、name=$(COMMAND)

 

变量引用:${name}、 $name

"":弱引用,其中的变量引用会被替换为变量值

'':强引用,其中的变量引用不会被替换为变量值,而保持原字符串

 

显示已定义的所有变量:set

销毁变量:unset name

 

环境变量:

变量声明、赋值:

export name=VALUE

declare -x name=VALUE

变量引用:$name, ${name}

显示所有环境变量:

export

env

printenv

销毁:unset name

 

Note:bash有许多内建的环境变量:PATH、SHELL、UID、HISTSIZE、 HOME、PWD、OLD、 HISTFILE、PS1

 

变量命名法则:

1、不能使程序中的保留字:例如if, for

2、只能使用数字、字母及下划线,且不能以数字开头

3、见名知义

 

只读变量:

readonly name

declare -r name

 

位置变量:

在脚本代码中调用通过命令行传递给脚本的参数;

$1, $2, …:对应调用第1、第2等参数;

shift [n]:可以用来向左移动位置参数。

$0:命令本身

$*:传递给脚本的所有参数,整体一行字串

$@:传递给脚本的所有参数,是一个列表

$#:传递给脚本的参数的个数

 

11、编程环境

程序编程风格:

过程式:以指令为中心,数据服务于指令

对象式:以数据为中心,指令服务于数据

 

shell程序:提供了编程能力,解释执行

过程式编程:

(1)顺序执行

(2)循环执行

(3)选择执行

shell脚本:文本文件

shebang:

#!/bin/bash

#!/usr/bin/python

#!/usr/bin/perl

        运行脚本:

1、给予执行权限,通过具体的文件路径指定文件执行

2、直接运行解释器,将脚本作为解释器程序的参数运行

 

12、配置文件

按生效范围划分,存在两类:

全局配置:

/etc/profile

/etc/profile.d/*.sh

/etc/bashrc

个人配置:

~/.bash_profile

~/.bashrc

 

按功能划分,存在两类:

profile类:为交互式登录的shell提供配置

全局:/etc/profile, /etc/profile.d/*.sh

个人:~/.bash_profile

功用:

(1) 用于定义环境变量

(2) 运行命令或脚本

bashrc类:为非交互式登录的shell提供配置

全局:/etc/bashrc

个人:~/.bashrc功用

(1)定义命令别名

(2) 定义本地变量

 

shell登录:

交互式登录:

直接通过终端输入账号密码登录;

使用“su – UserName”或“su -l UserName”切换的用户

/etc/profile –> /etc/profile.d/*.sh –> ~/.bash_profile –> ~/.bashrc –> /etc/bashrc

非交互式登录:

su UserName

图形界面下打开的终端

执行脚本

~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh

 

编辑配置文件定义的新配置的生效方式:

(1) 重新启动shell进程

(2) 使用source或.命令进程

 

13、算术运算

+, -, *, /, %, **实现算术运算:

(1) let var=算术表达式

(2) var=$[算术表达式]

(3) var=$((算术表达式))

(4) var=$(expr arg1 arg2 arg3 …)

 

Note:乘法符号有些场景中需要转义

Note:bash有内建的随机数生成器:$RANDOM

 

增强型赋值:+=, -=, *=, /=, %=

let varOPERvalue

                        例如:let count+=1

 

自增,自减:

let var+=1

                        let var++

let var-=1

                        let var–

 

 

14、条件测试

条件测试:判断某需求是否满足,需要由测试机制来实现

Note: 专用的测试表达式需要由测试命令辅助完成测试过程

 

测试命令:

test EXPRESSION

[ EXPRESSION ]

` EXPRESSION `

 

Note: EXPRESSION前后必须有空白字符

 

bash的测试类型:

  1. 数值测试

  2. 字串符测试

  3. 文本测试

 

(1)数值测试:

-gt: 是否大于

-ge: 是否大于等于

-eq: 是否等于

-ne: 是否不等于

-lt: 是否小于

-le: 是否小于等于

 

(2)字符串测试:

==:是否等于

>: 是否大于

<: 是否小于

!=: 是否不等于

=~: 左侧字符串是否能够被右侧的PATTERN所匹配

Note: 此表达式一般用于` `中

-z "STRING":测试字符串是否为空,空则为真,不空则为假

-n "STRING":测试字符串是否不空,不空则为真,空则为假

Note:用于字符串比较时的用到的操作数都应该使用引号

 

(3)文件测试:

存在性测试:

-a FILE

-e FILE: 文件存在性测试,存在为真,否则为假

存在性及类别测试:

-b FILE:是否存在且为块设备文件

-c FILE:是否存在且为字符设备文件

-d FILE:是否存在且为目录文件

-f FILE:是否存在且为普通文件

-h FILE 或 -L FILE:存在且为符号链接文件

-p FILE:是否存在且为命名管道文件

-S FILE:是否存在且为套接字文件

文件权限测试:

-r FILE:是否存在且可读

-w FILE: 是否存在且可写

-x FILE: 是否存在且可执行

文件特殊权限测试:

-g FILE:是否存在且拥有sgid权限

-u FILE:是否存在且拥有suid权限

-k FILE:是否存在且拥有sticky权限

文件大小测试:

-s FILE: 是否存且非空

文件是否打开:

-t fd: fd表示文件描述符是否已经打开且与某终端相关

-N FILE:文件自动上一次被读取之后是否被修改过

-O FILE:当前有效用户是否为文件属主

-G FILE:当前有效用户是否为文件属组

双目测试:

FILE1 -ef FILE2: FILE1与FILE2是否指向同一个设备上的相同inode

FILE1 -nt FILE2: FILE1是否新于FILE2

FILE1 -ot FILE2: FILE1是否旧于FILE2

 

15、自定义退出状态码

exit [n]:自定义退出状态码

Note:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

Note:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码