您的位置:首页 > 运维架构 > Shell

Shell程序及Linux中默认的Shell程序Bash的特性

2017-10-27 11:53 253 查看
SHELL:
一方面指用户与操作系统之间完成交互式操作的接口程序的统称,可以为用户提供简化的操作;
另一方面指shell也是一种程序语言;

在上世纪70年代中期,著名的实验室中的实验人员Bourne发明了bourne shell程序,简称sh;之后美 国计算机科学家 Bill joy根据bourne shell用C语言重新编译C bourne shell,简称csh,后来的衍生版 名为tcsh;之后David korn集合csh和sh的优点发明korn shell,简称ksh;开源组织GNU在比较这几 代的shell程序后发明bourne again shell,简称bash,进而成为Linux系统中默认的shell程序;再然后 进阶为zsh,也是最终shell,功能非常强大;因为bash是Linux中的默认shell程序,先入为主,zsh并 没有撼动bash的默认地位。

当前系统中所有可以支持的安全shell:
cat /etc/shells



注意:除了/sbin/nologin之外,其他shell都可以用来测试使用:

在更换shell时,最好在bash中更换其他shell



如果已经换成了其他shell,就使用exit命令返回至bash,再行切换



切勿进行一下切换方式,这种方式是错误的,会对系统造成很大的压力和负荷



如上的连续的shell程序切换,只是在已经切换的tcsh中又打开了csh的shell程序,又在csh中打开了bash程序,会对系统造成很大的压力,之后只要按如下操作退出,可以以echo $0的命令来查看当前使用的shell程序,如下:




BASH的特性:
一、命令的别名--(自定义命令)
alias:
定义或显示别名



命令格式:
alias [-p] [名称[=值] ... ]
注意:如果alias命令不带任何选项和参数,则表示显示所有已经定义并生效的别名设置;

# alias ALIAS='COMMAND [OPTION]...[ARGUMENT]...'



上图中,我们自定义命令mp等价于复制目录的命令‘mkdir -p’,在




unalias:
从别名定义列表中删除每一个“名字‘
命令格式:
unalias [-a] 名称 [名称 ...]




注意:
无论使用alias命令还是unalias命令,其功能都会立即生效;此二命令的生命期仅为当前shell的生命期,一旦注销登录,就相当于关闭了bash,则使用alias命令定义的别名或使用unalias命令删除的别名操作,会立即失效;

对于每个用户来说,都有一个私有的bash的配置文件,就在用户的家目录中的一个隐藏文件,文件名为“.bashrc”,其主要功能是用来保存命令的别名。






注意:
在对于此文件中的命令别名进行编辑并保存之后,在当前已经运行的bash中并不会立即生效,需要重新加载此文件才能使配置生效,以下两种操作皆可实现:
1.重启bash:注销之后再次登录即可:
2.执行文件中定义的命令:使用source或.;
source/. :
在当前 shell 中执行一个文件中的命令;
格式:
source 文件名 [参数]
. 文件名 [参数]




二、bash的快捷键:
C:Ctrl键
M:Alt键
E:Esc键
DEL:backspace键

C+l:清屏,Ctrl+L;
C+a:将光标跳转至命令行编辑模式的行首;
C+e:将光标跳转至命令行编辑模式的行尾;
C+k:删除光标所在位置至行尾的内容;
C+u:删除命令行编辑模式的光标所在位置至行首的内容;
C+c:结束前台进程;
M+.:引用上一个命令中的最后一个参数;(在Xshell中不可使用)
Esc+.:引用上一个命令中的最后一个参数(功能同M+.);

三、命令历史:
bash进程会保存其会话中的用户曾经执行过的命令,以方便用户重复执行某个命令操作;
命令历史包括两个方面:
1.用户曾经执行过的命令;
2.用户曾经执行过的命令的路径;

在bash中有一个内置的变量--PATH,PATH变量的值为当前所有系统中所有命令的文件的所在路径的集合



shell程序执行命令的过程:
bash会将命令行的内容按照空白字符进行切片,分析第一个切片内容:
1.判断第一个切片的内容是外部命令还是外部命令;
如果是内部命令,直接执行;
如果是外部命令,先找hash表中的路径缓存,如果有,则直接执行;否则需要通过查找PATH变量中包含路径中

,是否有对应名称的文件;



使用hash命令查看被记住的命令文件的路径:
-r:清空hash表;
使用history命令查看被记住的命令的命令行参数;
history:
显示或操纵历史列表;
格式:
history [-c] [-d 偏移量]
或 history -anrw [文件名] 或 history -ps 参数 [参数...]
常用选项:
-c:删除所有条目从而清空历史列表;
-d OFFSET 偏移量:从指定位置删除历史列表




(如图所示,原来所在的198行的历史*已被删除);

重复执行历史缓冲区中的命令:
!NUMBER:重复执行历史缓冲区中编号为“NUMBER”的命令


!STRING:重复执行历史缓冲区中以“STRING”开头的最后一次执行过的命令


!-NUMBER:重复执行历史缓冲区中倒数第“NUMBER”条命令



使用上、下箭头可以从历史缓冲区中调用命令,回车之后执行;
C+r:在历史缓冲区中实施搜索,回车之后执行


!$:在历史缓冲区中调用最后一个命令的最后一个参数


!^:在历史缓冲区中调用最后一个命令的第一个位置的参数


!:NUMBER:在历史缓冲区中调用最后一个命令的第“NUMBER”位置的参数



!SEQUENCE:NUMBER:在历史缓冲区中调用第“SEQUENCE”条命令的第“NUMBER”位 置的参数

(在历史缓冲区中223条位置的 第二条命令);

在bash中与命令历史相关的内置变量:
HISTSIZE:历史缓冲区中能够保存的命令历史的最大条目数量,默认1000



HISTFILESIZE:~/.bash_history文件中能够保存的命令历史的最大条目数,默认是1000;
HISTTIMEFORMAT:在命令历史缓冲区中记录历史命令时;同时记录命令的执行的时间戳标记;可以使用date命令的FORMAT来表示时间的记录格式,默认值为空




HISTCONTROL:控制命令历史的记录方式


ignoredups:忽略连续且相同的命令被记录到历史缓冲区;此为默认值;
ignorespace:忽略以空白字符开头的命令不会被记录到历史缓冲区;
ignoreboth:上述两种情况都不会被记录到历史缓冲区;

四、命令补全(Tab键的使用:单击补全,双击补出所有可能的内容):
1、构成命令字符串的补全;
参考PATH变量中的路径,对命令进行补全:
如果给出的字符串是PATH变量中对应的路径是唯一的,则直接补全命令;
如果给出的字符串是PATH变量中对应的路径不唯一,则bash给出提示;
2、命令中参数所对应的字符串的补全;
根据给出的路径进行补全:
如果给出的字符串是PATH变量中对应的路径是唯一的,则直接补全命令;
如果给出的字符串是PATH变量中对应的路径不唯一,则bash给出提示;

五、命令行展开:
1.~展开:
~:bash会自动将波浪线展开为当前登录用户的家目录 ;
~STRING:bash会自动将其展开为以“STRING”为用户名的用户的家目录


(左图为用户cl家目录中的目录列表);

利用getent passwd命令来查看当前系统内的所有用户,如下:



~+:调用bash的内置变量“PWD”的值;
~-;调用bash的内置变量“OLDPWD”的值;

2.{}展开:
在“{}”中,可以填充一个以","来分隔的路径列表,bash会将其展开为多个独立的路径;
示例:
mkdir -pv /china/{hb,hn,jl,hlj,ln}/{link,linka,linkb}/class18



# cp 1.txt{,.bak}
1.txt{,bak} == 1.txt 1.txt.bak




六、命令的执行结果
在bash中,命令的执行结果有两种:
1.执行命令的输出结果;
根据用户的需求获取到的命令执行的正常输出结果;
命令引用或命令替换:

`` 相当于 $()
``:反向单引号,反引号;
示例:
创建一个文件,文件名为test-系统时间;
touch test-`date +%F-%H-%M-$S`


2.执行命令的状态返回值;
与此前的一个命令是否成功执行的返回内容;
bash使用一个特殊的内置变量来保存其内容:$?
$?实际上保存的是一个数值,其取值范围:0~255
其中:
0:表示命令执行成功


1-255:表示命令执行失败;
1,2,127:bash中内置的命令执行失败的状态返回值;
1:表示小问题


2:表示严重问题;
127:表示命令本身出现问题


其余数字(3-126,128-255):用户可以自定义的失败状态返回值;

七、引用功能:
'':强引用
凡是被单引号引用的内容,bash在处理时,一律视其为普通字符,

即使其本身是bash定义的具有特殊功能和作用字符亦是如此,但单引号本身除外,如

需要成对儿出现;

"":弱引用
凡是被双引号引用的内容,bash在处理时,

有些特殊字符仍然会保留其特殊含义,如$,\,"";

八、转义功能:
\:bash定义的转义字符;大多数情况下,“\”只能将其后面一个字符转义;

\COMMAND:取消定义过的命令别名,而使用命令本身的功能;



上图就是反斜线发挥作用的结果;

九、Globbing--文件名通配符,简称为glob;
*:匹配任意长度的任意字符或字符串;(某些特殊位置的“.”字符不能匹配;)
?:匹配任意单个字符;(不能匹配“.”)
[]:匹配指定范围内的任意单个字符,必须匹配且只能匹配一个字符;
指定范围的方法:
1、枚举法:列出所有有效字符;
2、范围指定:
[0-9]:表示所有单个的十进制数字;
[a-z]:除大写Z外的所有英文字母无论大小写;
[A-Z]:除小写字母a外的所有英文字母无论大小写;
3、bash内建字符集:
[:lower:]:所有的小写字母;
[:upper:]:所有的大写字母;
[:alpha:]:所有的字母,包括大小写;
[:digit:]:所有单个的十进制数字;
[:alnum:]:所有的字母和十进制数字;
[:punct:]:所有的符号;
[:space:]:空白字符,包括空格和制表符;
4、反向匹配:
^ 示例:ls a[^[:digit:]]?? //表示文件名的第二个字符不能是十进制数字
注意:当中括号中有脱字符有“^”表示字符集反向匹配时,注意“*”的使用;因为“*”的通配范围可能会导致反向匹配失败;此类失败是因为bash的globbing是在贪婪模式下匹配的;

十、管道
|
管道通常用来连接多个命令的,将管道符号前面的命令的执行的输出结果通过管道传递给管道符号后面的命令,让后面的命令将前面的命令的输出结果当成参数来使用;

wc:
print newline, word, and byte counts for each file
格式:
wc [OPTION]... [FILE]...
常用选项:
-c, --bytes:仅显示文件中的字节数;
-m, --chars:仅显示文件中的有效字符的数量;
-l, --lines:仅显示文件中的行数;
-w, --words:仅显示文件中的数量;



注意:1、一般来讲,凡是被管道连接的命令,都应该能够执行成功之后完成命令结果的输出,否则管道无意义;
2、管道不是万能的,有些场合没办法使用管道的;

十一、输入输出重定向
在使用计算机的时候,实现某个功能的主体是程序!
程序=指令 + 数据
数据至关重要!

文件,IO---输入input和输出output
在Linux系统中,能够完成输入和输出功能的实体:文件;

可以用于输入的设备:文件
键盘设备、文件系统中的常规文件、网卡设备、声卡设备等;

可以用于输出的设备:文件
显示器、文件系统中的常规文件、网卡设备、声卡设备、磁盘设备等;

在内存中使用内存的方法是定义文件描述符,一个文件描述符就对应一个文件;
0:表示标准输入,stdin,从键盘实现的输入数据流;
1:表示标准输出,stdout,到显示器的输出数据流;
2:表示标准错误,stderr,到显示器的错误数据流



输入输出重定向(IO重定向)
采用非标准设备文件实现的IO操作;

输入重定向:
<

输出重定向:
>:覆盖输出重定向;
set -C:开启防止意外覆盖源文件开关,可以使用">|"符号完成覆盖重定向
set +C:开启防止意外覆盖源文件开关;



>>:追加输出重定向;




错误重定向:
2>:覆盖错误重定向;
2>>:追加错误重定向;

合并标准输出和标准错误的重定向:
1.COMMAND {>|>>} /PATH/TO/SOMEFILLE 2>&1
2.&>,&>>




特殊的设备文件:
/dev/null:blackhole(黑洞),blackbucket(位桶); 输出
/dev/zero:泡泡机,吐零机; 输入

bash中的其他特殊符号:
<<:here document,此处文档,结束标记;(跟输入重定向没有任何关系)



<<<:here string,此处字符串,结束标记;



bc命令为计算器,在这里<<<把后面的79/8整合为字符串送到前面的bc去执行。

十二、bash变量
变量:一段有名称的连续的内存空间;
变量名:这段内存空间的名称,称为变量名;
变量值:在这段内存空间中存储的数据,则称为变量值;

向内存空间(变量)中存储数据的过程,称为赋值操作;赋值符号通常为"=";

变量的类型:
123 -- 整型:01111011
-- 字符型:ASCII:3字节
-- 字符型:UTF-8:9字节
(变量类型不一样,占据的内存空间也不一样)

变量分为:
强变量:使用之前必须事先声明,必须声明变量类型;
弱变量:在使用之前无需声明,无需指明变量类型;(bash变量)

变量的赋值方法:
VARNAME=VALUE
含义:将某数值(VALUE)通过赋值操作(=)存储于特定的内存空间中(VARNAME);

bash中变量名称的命名规范:
1.变量名只能以"_"或"字母"为起始字符,后面的其他字符可以是任意字母,数字或下划 线;
2.变量名中的字母大小写敏感;
3.命名的书写格式:
全大写:HISTSIZE
全小写:myvar
驼峰式:MyNewVariable
连接式:My_New_Var
4.变量名要能做到见名知意;
5.变量名不能与已知变量或bash的内置变量重复;

bash中的变量的分类:
根据变量的作用范围来划分:
全局变量(环境变量):作用范围为整个shell进程,包括其子shell;
本地变量:作用范围为当前登录时打开的shell进程,不包括其子shell;
局部变量:作用范围仅仅只是当前程序段,一般用于函数;

根据变量的声明方式来划分:
bash内置变量:
普通的内置变量:HISTSIZE,...
位置参数变量:$0, $1, $2, ...



touch存储的位置就是$0 $1 $2 $3 $4
特殊变量:$?, $#, $*, $@, $$, ...
$?:展开为最近一次执行的命令的状态返回值(退出状态码);用以表示最近一 次执行的命令是否成功执行;
$#:不包括$0在内的其余的位置参数的个数,以十进制数字表示;
$*:从$1开始展开为位置参数。当使用双引号引用展开的结果时,它展开为 特殊变量IFS的第一个字符分隔的值;
$@:从$1开始展开为位置参数。当使用双引号引用展开的结果时,它展开为 一个单独的字符串;
$$:展开为当前shell的进程标识符;
自定义变量:用户可以自定义的变量;

变量的使用:
1.变量的声明(所有声明的变量都是自定义变量)和赋值:
1) 声明全局变量(环境变量):
export:
export VARNAME
export VARNAME=VALUE
可以声明,也可以直接声明后进行赋值操作,如下图:



declare命令:
declare - Set variable values and attributes.
格式:declare [-aAfFgilrtux] [-p] [name[=value] ...]
常用的选项:
-a:声明索引数组(如果支持)
-A:声明关联数组(如果支持)
-i:声明整型变量
-l:声明变量并将变量值中的字母转换为小写字母


;
-u:声明变量并将变量值中的字母转换为大写字母;
-r:声明只读变量;该变量仅能进行一次赋值操作;
-x:声明变量并将其导出为全局变量;
声明为全局变量:
declare -x VARNAME[=VALUE]

声明全局变量后,变量就可以在当前shell及其子进程的shell中使用;

2) 声明本地变量:
VARNAME=VALUE
本地变量直接声明,声明后的变量只可以在当前的shell中使用,作用范围
只在当前shell中;
3) 声明局部变量:
local VARNAME[=VALUE]
仅仅是在函数中使用的变量;

2.查看环境变量:
set命令:查看和改变shell属性的值及查看shell变量的变量名和变量值;
export命令:查看变量名称,也可以为变量赋值;
env命令:与export命令类似;

3.查看变量的值:
echo ${VARNAME}



4.撤销变量的赋值及变量声明
unset VARNAME




有关于保存变量的shell配置文件:
通用配置文件(在系统启动的时候就已经加载好的配置文件):
/etc/bashrc
/etc/profile
/etc/profile.d/*

私人配置文件(在家目录下的隐藏文件中,只有此用户登录后才会加载的配置文件):
~/.bashrc



~/.bash_profile




注意:
1.一般情况下,变量都是随用随声明,除非有必要,否则不建议修改配置文件的内容;
2.声明的变量在使用完以后,最好使用unset命令予以撤销;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux 程序 shell