Linux 上 Bash 的基础特性

1、命令历史

shell进程会在其会话中保存此前用户提交执行过的命令。
(1)~]# history
定制history的功能,可通过环境变量实现:
1)HISTSIZE:shell进程可保留的命令历史的条数;
2)HISTFILE:持久保存命令历史的文件;
3).bash_history:用户登出时保存命令历史的文件(用户家目录下的隐藏文件)。每次用户登录,将.bash_history文件中的命令加载到内存中,之后在shell中执行history,显示的是内存中的命令,包括登录时加载的.bash_history命令和刚刚输入的命令。cat .bash_history 显示的是.bash_history中的命令,没有刚刚输入的命令,因为只有在用户登出时才将刚刚输入的命令保存到.bash_history文件中。
4)HISTFILESIZE:命令历史文件的大小。
命令用法:
(2)history [-c] [-d 偏移量] [n] 操作文件
history -anrw [文件名]
history -ps 参数 [参数...]
-c: 清空命令历史;
-d offset:删除指定命令历史;
(3)history -d offset n:从命令编号为offset开始删除n条;
-r:从文件读取命令历史至历史列表中;
-w:把历史列表中的命令追加至历史文件中;
(4)history #:显示最近的#条命令;
(5)调用命令历史列表中的命令:
!#:再一次执行历史列表中的第#条命令;
!!:再一次执行上一条命令;
!STRING:再一次执行命令历史列表中最近一个以STRING开头的命令;
注意:命令的重复执行有时候需要依赖于幂等性;
(6)调用上一条命令的最后一个参数:
快捷键:ESC, . (ESC松开后再按.)
快捷键:Alt+. (按住Alt再按.)
字符串:!$ (直接输入!$)
需要注意的是:连续执行相同的命令,在历史记录里面只记录一次。
(7)控制命令历史记录的方式:
环境变量:HISTCONTROL(在/etc/profile配置文件中控制)
ignoredups:忽略重复的命令,连续且相同方为“重复”;
ignorespace:忽略以空白字符开头的命令;
ignoreboth:以上两者同时生效;
修改变量的值:NAME=‘VALUE’
eg. HISTCONTROL=ignorespace ,该修改仅对当前shell进程有效。
环境变量修改永久生效:export 变量名=“值”

2、命令操作

(1)命令补全
shell程序在接收到用户执行命令的请求,分析完成之后,最左侧的字符串会被当作命令。
命令查找机制:

  1. 查找内部命令;
  2. 查找外部命令:根据PATH环境变量中设定的目录,自左而右逐个搜索目录下的文件名。

给定的打头字符串如果能惟一标识某命令程序文件,则直接补全;不能惟一标识某命令程序文件,再击tab键一次,会给出列表。
(2)路径补全
在给定的起始路径下,以对应路径下的打头字串来逐一匹配起始路径下的每个文件。
如果能惟一标识,则直接补全;否则,再一次tab,给出列表。
(3)命令行展开
~:自动展开为用户的家目录,或指定的用户的家目录;
{}:可承载一个以逗号分隔的路径列表,并能够将其展开为多个路径;
例如:/tmp/{a,b} 相当于 /tmp/a /tmp/b
(4)命令的执行状态结果
bash通过状态返回值来输出此结果:成功返回0,失败返回1-255之间的值。
命令执行完成之后,其状态返回值保存于bash的特殊变量$?中。
命令正常执行时,有的还会有命令返回值,根据命令及其功能不同,结果各不相同。
引用命令的执行结果:$(COMMAND)COMMAND

3、引用

强引用:’ ',其中任何内容直接显示,不做替换。
弱引用:" ",其中变量做变量替换,将出现变量的地方替换成变量的值。
命令引用:``

4、快捷键

Ctrl+a:跳转至命令行行首;
Ctrl+e:跳转至命令行行尾;
Ctrl+u:删除行首至光标所在处之间的所有字符;
Ctrl+k:删除光标所在处至行尾的所有字符;
Ctrl+l:清屏,相当于clear;
Ctrl+c:取消命令的执行;

5、globbing

globbing用于文件名通配,是整体文件名匹配,而非部分文件名匹配。
匹配模式
(1)* :匹配任意长度的任意字符;
例:pa*, * pa *, * pa, *p * a *
(2)?:匹配任意单个字符;
例:pa?, ??pa, p?a, p?a?
(3)[]:匹配指定范围内的任意单个字符;
有几种特殊格式:
1)[a-z], [A-Z], [0-9], [a-z0-9];
2)[[:upper:]]:所有大写字母;
3)[[:lower:]]:所有小写字母;
4)[[:alpha:]]:所有字母;
5)[[:digit:]]:所有数字;
6)[[:alnum:]]:所有的字母和数字;
7)[[:space:]]:所有空白字符;
8)[[:punct:]]:所有标点符号;
(4)[^]:匹配指定范围外的任意单个字符;
例:[ ^ [:upper:]],[ ^ 0-9],[ ^ [:alnum:]];
例1:显示/var目录下所有以l开头,以一个小写字母结尾,且中间出现一位任意字符的文件或目录:
ls -d /var/l?[[:lower:]]
例2:显示/etc目录下,以任意一位数字开头,且以非数字结尾的文件或目录:
ls -d /etc/[0-9]*[^0-9]
例3:显示/etc目录下,以非字母开头,后面跟一个字母及其它任意长度任意字符的文件或目录:
ls -d /etc/[^a-z][a-z]*
例4:复制/etc目录下,所有以m开头,以非数字结尾的文件或目录至/tmp/magedu.com目录:
cp -r /etc/m*[^0-9] /tmp/magedu.com/
例5:复制/usr/share/man目录下,所有以man开头,后跟一个数字结尾的文件或目录至/tmp/man/目录下:
cp -r /usr/share/man/man[0-9] /tmp/man/
例6:复制/etc目录下,所有以.conf结尾,且以m,n,r,p开头的文件或目录至/tmp/conf.d/目录下:
cp -r /etc/[mnrp]*.conf /tmp/conf.d/

6、IO重定向

(1)可用于输入的设备:键盘设备、文件系统上的常规文件、网卡等;
可用于输出的设备:显示器、文件系统上的常规文件、网卡等;
(2)程序的数据流有三种:
输入的数据流 <-- 标准输入(stdin)(键盘);
输出的数据流 --> 标准输出(stdout)(显示器);
错误输出流 --> 错误输出(stderr)(显示器);
标准输入用0表示,标准输出用1表示,错误输出用2表示。
(3)IO重定向
输出重定向:>
(特性:覆盖输出)
输出重定向:>>
(特性:追加输出)
输入重定向:<
Here Document:<< 此处创建文档,把所输入的内容创建为文档。
(4)输出重定向
set命令:
设置或撤销shell选项的值和位置参数
# set -C
禁止覆盖输出重定向至已存在的文件,该命令仅对当前shell进程有效,此时可使用强制覆盖输出:>|。
# set +C
关闭上述特性。
错误输出流重定向:2>, 2>>
例:[root@localhost exercise]# cat /etc/issue1 2> issue1.err
合并正常输出流和错误输出流:
1)&>, &>>
例:cat /etc/fstab3 &> fstab3.out
2)COMMAND > /path/to/somefile 2>&1 覆盖输出
COMMAND >> /path/to/somefile 2>>&1 追加输出
例:cat /etc/rc.d/init.d/functions2 >> function.out 2>&1
特殊设备:/dev/null 数据黑洞

[root@localhost exercise]# ls /varr &> /dev/null
[root@localhost exercise]# echo $?
2
[root@localhost exercise]# ls /var &> /dev/null
[root@localhost exercise]# echo $?
0
对输出结果不关心,关心命令的状态结果

(5)输入重定向:<
tr命令:
tr [OPTION]... SET1 [SET2]
把输入的数据当中的字符,凡是在SET1定义范围内出现的,通通对位转换为SET2出现的字符。
1)用法1:
tr SET1 SET2 < /PATH/FROM/SOMEFILE
将SOMEFILE中SET1中出现的字符替换成SET2,并输出至屏幕(SOMEFILE原文件不改变)。
2)用法2:
tr -d SET1 < /PATH/FROM/SOMEFILE
从SOMEFILE中移除SET1中的字符,并输出至屏幕(SOMEFILE原文件不改变)。
注意:不修改原文件。

[root@localhost exercise]# tr [a-z] [A-Z]
how are you?
HOW ARE YOU?				
[root@localhost exercise]# tr [a-z] [A-Z] < /etc/issue
\S
KERNEL \R ON AN \M				
[root@localhost exercise]# tr -d 'abc' < /etc/issue
\S
Kernel \r on n \m				
[root@localhost exercise]# tr -d '[A-Z]' < /etc/issue
\S
ernel \r on n \m
[root@localhost exercise]# cat /etc/issue
\S
Kernel \r on an \m

把/etc/passwd文件的前6行的信息转换为大写字符后输出:
head -n 6 /etc/passwd | tr 'a-z' 'A-Z'
或者:[root@localhost exercise]# cat /etc/passwd | head -6 |tr 'a-z' 'A-Z'

(6)Here Document:<< 此处创建文档,把所输入的内容创建为文档
cat << EOF EOF为结束符
cat > /PATH/TO/SOMEFILE << EOF

[root@localhost exercise]# cat << EOF
> how are you?
> what are you doing?
> EOF
how are you?
what are you doing?
[root@localhost exercise]# cat > cat.out <<END
> how are you?
> what are you doing?
> END
[root@localhost exercise]# cat cat.out
how are you?
what are you doing?

7、管道

管道:连接程序,实现将前一个命令的输出直接定向后一个程序当作输入数据流,前一个命令的输出作为后一个命令的输入。
COMMAND1 | COMMAND2 | COMMAND3 | ...

[root@localhost exercise]# cat /etc/issue | tr 'a-z' 'A-Z'
\S
KERNEL \R ON AN \M						 
[root@localhost exercise]# who
root     :0           2016-11-16 07:21 (:0)
root     pts/0        2016-11-16 07:21 (:0)
root     tty2         2016-11-16 07:25
[root@localhost exercise]# who | head -2
root     :0           2016-11-16 07:21 (:0)
root     pts/0        2016-11-16 07:21 (:0)
[root@localhost exercise]# who | head -2 | tr 'a-z' 'A-Z'
ROOT     :0           2016-11-16 07:21 (:0)
ROOT     PTS/0        2016-11-16 07:21 (:0)
[root@localhost exercise]# who | head -2 | tr 'a-z' 'A-Z' | tr -d '0-9'
ROOT     :           -- : (:)
ROOT     PTS/        -- : (:)

(1)tee命令
从标准输入读入,并写往标准输出和文件。
COMMAND | tee /PATH/TO/SOMEFILE

[root@localhost exercise]# cat /etc/issue | tee issue.tee | tr 'a-z' 'A-Z'
\S
KERNEL \R ON AN \M
[root@localhost exercise]# cat issue.tee
\S
Kernel \r on an \m

8、命令hash

(1)hash的作用
hash就是记录或显示程序的位置(可执行程序的位置)。如果我们执行程序,系统每次都要从目录里面查找可执行文件,如果目录里面有很多可执行程序,那每次都需要花费很多时间去找文件,这就势必导致系统响应很慢,当然这也很不现实。实际中是只有第一次才去完整查找命令执行文件的,然后将其查询的结果记录下来放置到缓存中,如果下次还需要执行同样的命令,那么就直接从缓存中找命令的执行文件,然后直接执行。
这个缓存就是一个key/value的存储,可以通过hash命令来查看这个命令的缓存结果,这里的value就是命令的可执行文件的路径,key是一段hash码。
将一个命令移入到另一个目录里面来执行该命令,如:mv /bin/ls /usr/bin/ls,再执行ls命令,会发现系统找不到ls命令了。
(2)hash的使用
hash:列出hash缓存,缓存此前命令的查找结果:key-value,key为搜索键,value为值;
通过内部命令获取帮助信息的方式来获取hash命令的使用方法:help hash
hash -d COMMAND:删除hash中的某一条命令,COMMAND不需要给完整路径,只需要给命令名称即可;
hash -r:清空hash缓存。

[root@localhost ~]# hash
hits	command
1	/usr/bin/grep
1	/usr/bin/ls
[root@localhost ~]# hash -d ls
[root@localhost ~]# hash
hits	command
 1	/usr/bin/grep
[root@localhost ~]# hash -r
[root@localhost ~]# hash
hash: hash table empty

9、变量

(1)变量类型定义了数据存储格式、存储空间大小、参与的运算种类、表示的数据范围等。变量有强类型和弱类型。强类型是指定义变量时必须指定类型、参与运算必须符合类型要求,如果调用未声明变量的,则会产生错误。弱类型是指无需指定类型,默认均为字符型,参与运算会自动进行隐式类型转换,变量无需事先定义可以直接调用。bash就属于弱类型的编程语言。
变量的类型有:字符型、数值型。数值型又分为整型和浮点型。
bash是弱类型语言,把所有变量统统视作字符型,当我们强行指明做数值加减运算时,可以转换为数值型。bash不支持浮点数据,除非我们借助外在工具。
变量声明:bash中的变量无需事先声明,相当于把声明和赋值过程同时实现。
变量替换:把变量名出现的位置替换为其所指向的内存空间中数据。
变量引用:${var_name}, $var_name
变量名:变量名只能包含数字、字母和下划线,而且不能以数字开头。
变量名:见名知义,命名机制遵循某种法则,不能够使用程序的保留字,例如if, else, then, while等等。
shell可以有子shell,子shell又可以有子shell,并且父shell和子shell的shell类型可以不同(如,父shell为bash,子shell为csh),使用exit退出当前shell,回到父shell。
(2)bash变量类型
本地变量:作用域仅为当前shell进程;
环境变量:作用域为当前shell进程及其子进程;
局部变量:作用域仅为某代码片断(函数上下文);
位置参数变量:向执行脚本的shell进程传递的参数;
特殊变量:shell内置的有特殊功用的变量;如 $ ?,用于表示命令执行的状态结果,0表示成功,1-255表示失败。
(3)本地变量
生效范围为当前shell进程,对当前shell之外的其他shell进程,包括当前shell的子shell进程均无效。
变量赋值:name=‘value’,其中value可以是直接字符串:name=“username”,变量引用:name="$username",也可以是命令引用:name=COMMAND(反引号),name= $(COMMAND)。
变量引用: $ name,$ {name}
“ ”:弱引用,其中的变量引用会被替换为变量值;
’ ':强引用,其中的变量引用不会被替换为变量值,而保持原字符串。
显示已定义的所有变量:set,CentOS6和CentOS7执行set不同,CentOS7会显示shell内置的函数;
撤销变量:unset name;注意:此处非变量引用;不加 $。

[root@localhost ~]# first_name=jerry
[root@localhost ~]# echo $first_name
jerry
[root@localhost ~]# unset first_name
[root@localhost ~]# echo $first_name

[root@localhost ~]# 

(4)环境变量:变量作用域可以用于子shell,可以多级继承
变量赋值:

1)export name=value
2)name=value
export name
3)declare -x name=value     declare是bash内嵌命令,可以导出变量;
4)name=value
declare -x name
declare -i name              声明整型变量(bash数值型变量只支持整型,不支持浮点型)

变量引用:${name}, $name
bash内嵌了许多环境变量(通常为全大写字符),用于定义bash的工作环境:
PATH, HISTFILE, HISTSIZE, HISTFILESIZE, HISTCONTROL, SHELL, HOME, UID, PWD, OLD, OLDPWD, PS1等。
查看环境变量:export, declare -x, printenv, env
撤销环境变量:unset name
只读变量:

1)declare -r name
2)readonly name

只读变量无法重新赋值,并且不支持撤销,存活时间为当前shell进程的生命周期,随shell进程终止而终止。
(5)局部变量:生效范围为当前shell进程中的某代码片段(通常指函数)。
(6)位置变量:$ 1,…,$ n,$ {10}来表示,用于在脚本代码中调用通过命令行传递给它的参数。
(7)特殊变量
$?:上个命令执行成功与否的结果;
$0:表示命令本身;
$#:传递给脚本参数的个数;
$*:传递给脚本的所有参数;
$@:引用传递给脚本的所有参数。

10、多命令执行

~]# COMMAND1; COMMAND2; COMMAND3; ...

11、逻辑运算

短路法则:
~]# COMMAND1 && COMMAND2
COMMAND1为“假”,则COMMAND2不会再执行,否则,COMMAND1为“真”,则COMMAND2必须执行。
~]# COMMAND1 || COMMAND2
COMMAND1为“真”,则COMMAND2不会再执行,否则,COMMAND1为“假”,则COMMAND2必须执行。

[root@localhost ~]# touch /tmp/test.etc && ls /etc > /tmp/test.etc
[root@localhost ~]# touchabc /tmp/test.etc2 && ls /etc > /tmp/test.etc2
bash: touchabc: command not found...
[root@localhost ~]# cat /tmp/test.etc2
cat: /tmp/test.etc2: No such file or directory

~]# id $username || useradd $username       如果username不存在,则创建他
[root@localhost ~]# id user1
id: user1: no such user
[root@localhost ~]# id user1 || useradd user1
id: user1: no such user
[root@localhost ~]# id user1
uid=1003(user1) gid=1003(user1) groups=1003(user1)
[root@localhost ~]# id user1 || useradd user1
uid=1003(user1) gid=1003(user1) groups=1003(user1)

12、bash的配置文件

(1)bash配置文件的分类
bash的配置文件分为两类:
profile类:为交互式登录的shell进程提供配置;
bashrc类:为非交互式登录的shell进程提供配置。
(2) shell进程的分类
按照登录类型将shell进程分为两类:交互式登录shell进程和非交互式登录shell进程。
交互式登录shell进程:
1)直接通过某终端输入账号和密码后登录打开的shell进程;
2)使用su命令:su - USERNAME, 或者使用 su -l USERNAME执行的登录切换。
非交互式登录shell进程:
1)su USERNAME执行的登录切换;
2)图形界面下打开的终端;
3)通过运行脚本,shell脚本的运行是通过运行一个子shell进程实现的。
(3)profile类配置文件
全局配置文件(对所有用户都生效):
/etc/profile 主配置文件
/etc/profile.d/* .sh 配置文件片段
用户个人配置文件(仅对当前用户有效):
~/.bash_profile
profile类配置文件功用:
1)用于定义环境变量;
2)运行命令或脚本。
(4)bashrc类配置文件
全局配置文件(对所有用户都生效):
/etc/bashrc
用户个人配置文件(对某一用户生效):
~/.bashrc
bashrc配置文件功用:
1)定义本地变量;
2)定义命令别名。
仅管理员可修改全局配置文件,普通用户没有权限编辑。
(5) 配置文件的读取顺序
交互式登录shell进程:
直接通过终端输入账号和密码登录,或者使用su -l USERNAME或su - USERNAME切换登录用户:
/etc/profile --> /etc/profile.d/* .sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登录shell进程:
使用su USERNAME或者图形界面下打开的终端,执行脚本
~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
(6)配置文件的生效
命令行中定义的特性,例如变量和别名作用域为当前shell进程的生命周期。
配置文件定义的特性,只对随后新启动的shell进程有效。
让通过配置文件定义的特性立即生效:
1)退出并重新登录;
2)让shell进程重读配置文件;

~]# source /PATH/FROM/CONF_FILE
~]# .  /PATH/FROM/CONF_FILE         .的意思就是source命令

(7)设置用户登录欢迎语句

[root@localhost exercise]# nano /etc/profile.d/welcome.sh
welcome.sh文件内容:
echo "Welcome aboard..."

不需要赋予权限,下次登录时即可加载该配置文件,全部用户登录时都可看到欢迎语句。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页