linux bash学习-shell简介
一、shell的作用
管理整个计算机硬件的其实是操作系统的内核(kernel),这个内核其实是需要被保护的,一般的用户只能通过shell来和内核通信的,以让内核达到我们想要达到的工作,因此我们必须要通过shell 将我们输入的命令与内核通信,好让内核来正确无误的完成特定的操作,如果不再用户和内核之间加这层保护的话,对于用户操作不当的时候,内核有可能会奔溃。
二、系统中关于shell的配置
当前系统可以使用的shell版本记载在/etc/shells中,如图所示,系统的某些服务在运行过程中会检查该文件以查询可使用的shell版本,同时在/etc/passwd会记录该用户或者该服务需要取得的shell的版本:

yaoqinchuan:x:1000:1000:yaoqinchuan:/home/yaoqinchuan:/bin/bash是该用户的记录,再说一下passwd的格式为name:password:uid:gid:comment:home:shell (comment 用来保存用户的真实姓名和个人细节,或者全名。home 指定用户的主目录的绝对路径。 )
三、bash shell的功能
bash 是GNU计划的重要工具软件,也是linux distribution 的标准shell,其主要兼容sh,并且依据一些用户需要而加强的shell版本。其主要的功能有
1、命令记忆功能(history)
~/.bash_history 记录了前一次登陆以前所执行的命令,至于这一次登陆所执行的命令都暂存在临时内存中,当成功注销系统后,该记忆才会同步到~/.bash_history中,可以使用history -c 来进行命令清空(可以安全一些),也可以使用history -w 来进行即使同步(因为默认是用户注销后才会同步),默认可以保存1000条,可以在/etc/profile中更改,使用!字符串s表示调用以字符串s命令开头的最近的目录。

2、命令与文件补全
[Tab]接在第一个命令中为命令补全;接在bash 命令后为文件补全
3、命令别名设置(alias)
可以使用alias 来进行命令别名的设置例如 alias lm='ls -al',就可以直接使用lm来替代ls -al 的命令了,使用unalias lm 来取消已经设定好的别名,alias 的优先级是高于bash原始命令与外部命令。

![]()
但是alias仅仅在登陆期间是有效的,在注销用户重新登陆后就无效了,为了使其在用户登陆期间有效,可以将其写入配置文件,可以将alias命令写入~/.bashrc或者/etc/profile、/etc/bashrc(为啥使用profile:简况来作为配置文件。。。)
vi /etc/profile可以看到,在/etc/profile文件中修改环境变量,在这里修改的内容是对所有用户起作用的,因此最好不要修改这个大环境,以免使得其他用户的某些设置失效,虽说它是具备这个能力的,,同样的对于/etc/bashrc也是一样的,比较常见的配置应该放在对于该用户的单独定制中。

vi ~./bash_profile和~/.bashrc,但是在使用~/.bash_profile的时候即使添加了alias也无法再重启后直接使用,但是~/.bashrc可以使用,主要原因是由于登陆方式不同导致的,下面具体说明到底哪些配置文件会在开机登陆时候被执行[1]。

全局(公有)配置,不管是哪个用户,登录时都会读取该文件。
(2)/etc/bashrc Ubuntu没有此文件,与之对应的是/ect/bash.bashrc
bash.bashrc 是交互式shell的初始化文件。
(3)~/.profile 某个用户读取的配置。
若bash是以login方式(使用非图像界面)执行时,读取~/.bash_profile,若它不存在,则读取~ /.bash_login,若前两者不存在,读取~ /.profile。
另外,图形模式登录时,此文件将被读取,即使存在~/.bash_profile和~/.bash_login。
(4)~/.bash_login
若 bash是以login方式执行时,读取~/.bash_profile,若它不存在,则读取~/.bash_login,若前两者不存在,读取~ /.profile。
(5)~/.bash_profile Unbutu默认没有此文件,可新建。
只有 bash是以login形式执行时,才会读取此文件。通常该配置文件还会配置成去读取~/.bashrc。
(6)~/.bashrc 该文件包含专用于某个用户的bash shell的bash信息,当该用户登录时以及每次打开新的shell时,该文件被读取.
当 bash是以non-login形式执行时,读取此文件。若是以login形式执行,则不会读取此文件。
(7)~/.bash_logout
注销时,且是longin形式,此文件才会读取。也就是说,在文本模式注销时,此文件会被读取,图形模式注销时,此文件不会被读取。
补充一点,/etc/rc.local是系统shell会执行的文件,linux启动后会退出的;/etc/profile 或 /etc/bash.bashrc是用户shell会的配置,我们一般的Shell是用户Shell的子进程,而非系统shell的子进程,所以如果在 /etc/rc.local中指定"alias ll='ls -a'"这样的别名,对登录系统后的shell是没用的。
某网友总结如下:
/etc/profile,/etc /bashrc 是系统全局环境变量设定
/etc/profile与/etc/bashrc的区别?
前一个主要用来设置一些系统变量,比如JAVA_HOME等等,后面一个主要用来保存一些bash的设置.
~/.profile,~ /.bashrc用户家目录下的私有环境变量设定
当登入系统时候获得一个shell进程时,其读取环境设定档有三步
1 首先读入的是全局环境变量设定档/etc/profile,然后根据其内容读取额外的设定的文档,如
/etc/profile.d和 /etc/inputrc
2 然后根据不同使用者帐号,去其家目录读取~/.bash_profile,如果这读取不了就读取~/.bash_login,这个也读取不了才会读取
~/.profile,这三个文档设定基本上是一样的,读取有优先关系
3 然后在根据用户帐号读取~/.bashrc
至于~/.profile与~/.bashrc的区别,都具有个性化定制功能
~/.profile可以设定本用户专有的路径,环境变量,等,它只能登入的时候执行一次
~/.bashrc也是某用户专有设定文档,可以设定路径,命令别名,每次shell script的执行都会使用它一次
下面是几个例子:
1. 图形模式登录时,顺序读取:/etc/profile和~/.profile
2. 图形模式登录后,打开终端时,顺序读取:/etc/bash.bashrc和~/.bashrc
3. 文本模式登录时,顺序读取:/etc/bash.bashrc,/etc/profile和~/.bash_profile
4. 从其它用户su到该用户,则分两种情况:
(1)如果带-l参数(或-参数,--login参数),如:su -l username,则bash是lonin的,它将顺序读取以下配置文件:/etc/bash.bashrc,/etc/profile和~ /.bash_profile。
(2)如果没有带-l参数,则bash是non-login的,它将顺序读取:/etc/bash.bashrc和~/.bashrc
5. 注销时,或退出su登录的用户,如果是longin方式,那么bash会读取:~/.bash_logout
6. 执行自定义的shell文件时,若使用“bash -l a.sh”的方式,则bash会读取行:/etc/profile和~/.bash_profile,若使用其它方式,如:bash a.sh, ./a.sh,sh a.sh(这个不属于bash shell),则不会读取上面的任何文件。
7. 上面的例子凡是读取到~/.bash_profile的,若该文件不存在,则读取~/.bash_login,若前两者不存在,读取~ /.profile。
因此在bash_profile中进行环境变量设定的时候需要注意登陆方式的选择,就是登陆方式选择错误导致alias设置不生效!在/etc/bashrc中我们看到下图内容,说明其可以执行/etc/profile.d的shell命令

4、作业控制、前台、后台
1. command& 让进程在后台运行
2. jobs 查看后台运行的进程
3. fg %n 让后台运行的进程n到前台来
4. bg %n 让进程n到后台去,在某个shell运行的时候使用ctrl -z暂停后使用bg n即可让程序后台运行;
使用nohup watch -n 0.5 df >test.out &将 nohup watch -n 0.5 df的结果重定向到test.out,其中nohup(no hang up)意味着不要挂起,持续执行,&表示后台运行,一般nohup和&搭配使用,>>表示以追加的方式将数据重定位到文件中,>表示以覆盖的方法加入,
注意一点是在使用command >>file 2>&1是输出信息与错误命令都使用追加的方式,后面的使用>而不是>>,也可以使用command &>>file。也可以使用command>>file 1 2>>errfile1来分开保存,注意此时2使用的是>>而不是>,把正确的结果放在file1中,但是把报错结果保存在errfile1中。
![]()
检查当前在运行的后台程序:jobs
![]()
将id为2的程序调到前台来,并且将其暂停
![]()
此时再观察发现id为2的程序已经由运行中变为已停止
![]()
使用bg %2让其执行,状态又变为了运行中

为了验证程序真的在运行我们可以监测test.out的大小,可以看到真的在运行。

在使用重定向的时候会提示警告,稍微学习一下这个警告是怎么来的,将watch的输出结果输出到test.out,那么其在产生错误的时候的结果error的提示信息输出到哪??,默认输出到屏幕,也就是标准输出设备

其中的2>&1的作用就是对于这种错误信息的处理
0 表示stdin标准输入
1 表示stdout标准输出
2 表示stderr标准错误
nohup watch -n 0.5 df >test.out 2>&1 &中watch -n 0.5 df相当于标准输出1,因此这条命令相当于nohup watch -n 0.5 df (1)>test.out 2>&1 &,不使用nohup watch -n 0.5 df >test.out 2>test.out &的目的为若使用该指令的话会两次打开test.out文件,效率很差,不如将错误重定向到标准输出(1),这样仅仅需要一次打开文件[2]。也可以使用/dev/null来将错误信息屏蔽掉。
5、程序脚本与通配符
可以使用shell将任务写成批处理文件,以后再说。同时使用通配符来帮助具体的操作,再回忆一下常见的通配符:
*:匹配0或者任意数量的字符。
?:匹配一个任意字符。
[0-9]:匹配任意范围的数字。
[a-z]:匹配小写字母。
[^]:逻辑非,不匹配某些内容。
$:查看变量名的实际值

'':直接表示字符串,在其中所有的特殊符号如$和'(反引号)都没有特殊含义
"":双引号内也可以表示字符串,但是”拥有变量的值“($)“引用命令”(`)和转义字符(\)是有特殊含义的

``(类似于$()):先执行``内部的命令,因此``内部是一个命令,被赋值的变量包含一个命令的结果

四、bash shell的内置命令 type
type的主要作用是查询所使用的命令是由bash提供的还是由外部提供的,主要的形式为 type [-tpa] name
参数为:
-t 显示来源,file(来意外部)、alias(来自于别名设置)、bulitin(bash 的内置命令)
-p 仅仅对于外部命令有效,显示外部命令的路径
-a 会由PATH查找变量定义的路径中包含name的所有命令都列出来,包括alias

五、多命令执行顺序与管道符
1、command 1;command 2 命令1与命令2各自执行,两个之间没有关系。
2、command1&&command2 命令1执行成功才执行命令2,命令1执行失败则不执行命令2。
3、command1||command2 命令1执行成功则不执行命令2,命令1执行失败执行命令2,类似于异或。

4、command1|command 管道命令,将command1的结果作为输入到command2中,或者作为command2的操作对象,注意与逻辑与的区别,command2必须要能够操作command1的输出,这是有逻辑关系的,因此使用更加常见。
![]()
常见的命令有command1&&echo yes||echo no,来判断命令command1是否执行成功
[1]https://www.cnblogs.com/hummersofdie/archive/2013/01/22/2871964.html
[2]https://blog.csdn.net/ggxiaobai/article/details/53507530

浙公网安备 33010602011771号