《Linux系统》之"深入浅出"(三)shell概述

一、什么是shell

到底什么是shell呢?我相信,这个问题,应该困扰过很多人吧?那么今天,我们就来好好捋一下这个概念。

首先,从英文单词上来理解,是“壳”的意思,用于区别“核”的概念,有“壳”保护“核”的涵义;这就好比“鸡蛋壳”与“鸡蛋黄”。然后我们再从计算机的角度来理解一下,计算机由一组硬件组成,,而内核(kernel)是用来管理和操纵这些硬件让其工作的。那么内核总不能让用户随意操作吧!对于公司来说,总会有菜鸟入职的,让他们随意操作内核,很容易造成系统崩溃。๑乛◡乛๑

因此,在内核之上又开发了一层应用程序。用户可以通过这样的应用程序来指挥内核,让内核管理相应的硬件来完成我们的任务。这样可以与内核进行直接交互的程序,我们就可以称之为shell。


Linux系统上的shell,实际上就是用户与Linux系统内核之间的接口程序,一种交互性命令解释器。用户在提示符界面输入的每一个命令,都要经由shell这个解释器来解释,然后传给内核,内核再继续往下工作。同样shell也能接收内核的输出信息,展示给用户。shell独立于操作系统,这种设计让用户可以灵活选择适合自己的shell。

Linux系统下存在多个shell,可以查看 /etc/shells文件来知晓系统内安装的shell,不过,最常用的shell还是/bin/bash。这个也是系统默认使用的shell。

[michael@master ~]$ cat /etc/shells
/bin/sh               <==Bourne Shell,已经被Bourne Again Shell取代
/bin/bash           <==Bourne Again Shell,系统默认使用的shell,兼容了Bourne Shell,功能更强大
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh

既然系统下有多个shell,我们应该有这样的问题需要思考:用户什么时候使用shell?用户使用的是哪一种shell呢?这两个问题,其实我们在讲解用户管理时,已经说到过了。还记得登录验证的工作流程吗?当输入密码后,会先验证/etc/passwd文件里是否有此用户名,如果有的话,就会读取uid和gid,再读取用户主目录和要使用的shell,密码校验成功后,就会获得这个shell开始工作了。

二、/bin/bash的简介

Linux系统下虽然有很多种shell,但是最常用的还是/bin/bash这个shell,同时也是市场上众多流行Linux版本默认使用的shell。/bin//bash在兼容/bin/sh的所有功能的同时,也有一些自己独特的功能。甚至可以说成bash已经完全取代了sh。那么bash都有哪些好用的功能呢,我来介绍一下吧。

1、命令记忆功能

这个功能真是非常的好用呢?因为bash能记住我们输入过的命令,因此,我们就可以通过“上、下键”来找到前一个或者是后一个命令。而bash记住命令的数量多达1000个,可以理解成你输入的命令bash几乎全都记录了下来。

这些命令暂时保存在内存中,当你成功注销当前用户时,这些命令就会存在主目录下的.bash_history文件中。

2、命令和文件名补全功能

正因为有了这个功能,用户少打了很多字母,同时也提高了书写的正确率,进而提高了工作效率。

在命令行的相应位置上,按两下Tab键,会有不同的效果,

第一个词后连按两下Tab键,是对命令进行查看或者补全
第二个词后连按两下Tab键,是对文件名进行查看或补全

3、命令别名设置功能

某些命令串或许经常使用,你是否因这些命令串的字符比较多而闹心呢?我相信应该是有的。bash中提供了别名的设置,这样就方便了用户对命令的使用。在bash下,通过alias对命令串进行起别名,然后我们使用别名就相当于使用命令串。

如 'ls -al'这样的命令串,当alias lm='ls -al'后,我们使用lm就相当于使用了 'ls -al'了,特别方便。

4、作业控制、前台、后台切换功能

我们可以将前台正在执行的任务,切换到后台运行,然后前台再开启一个新的任务,这样就可以达到一个窗口多任务的目的。

5、通配符功能

在bash中,也支持*这样的通配符,可以让用户更方便的来进行作业。如:ls ~/c*,表示查看主目录下c开头的文件。

6、编程语言功能

bash这个shell,本身就是一个编程语言,这个应该是bash中最强大的功能了。它支持多种编程语言里常见的特征,比如分支和循环结构,函数,变量和数组等。并且一旦掌握后它将成为你的得力工具。只要能在提示符界面上输入的命令都能放到一个可执行的shell程序里,这意味着用shell语言能简单地重复执行某一任务。

三、shell中的变量

学过编程语言的人,都应该知道变量的概念及其使用变量的优势所在。这里就不再累述了。我们来学习一下shell中变量的使用规范。

1、变量的命名规则

  • 命名只能使用英文字母,数字和下划线。首个字符不能以数字开头。
  • 字母习惯使用大写。
  • 中间不能有空格。
  • 不能使用标点符号。
  • 不能使用bash里的关键字(可用help命令查看保留关键字)

2、变量的使用规则

  • 直接定义变量名称,没有类型需要强调(类似于数学中:x=1,y=2,z=x+y)
  • 赋值时,"="前后不能有空格
  • 命令的执行结果赋值给变量时,使用反单引号      如:TIME=`date`
  • 使用变量时,必须使用$       格式: $变量名    或    ${变量名}

应用案例1:我们借助echo命令,来读取变量的值

[michael@master ~]$ MYNAME=kitty            <==定义变量MYNAME,同时赋值kitty
[michael@master ~]$ echo $MYNAME         <==借助echo命令,读取变量的值
kitty
[michael@master ~]$ echo $YOURNAME
                                                   <==为空,因为YOURNAME这个变量尚未定义。
[michael@master ~]$ ADDR=长春;echo $ADDR     <==一个命令行中,使用分号(;)隔开
长春

应用案例2:变量多次赋值

[michael@master ~]$ ADDR="上海"
[michael@master ~]$ echo $ADDR
上海
[michael@master ~]$ ADDR='北京'
[michael@master ~]$ echo $ADDR
北京

3、只读变量和删除变量

使用readonly 可以将变量设置成只读形式,这样的变量就不可以再次被赋值了,从而防止变量的值被不经意的修改。

[michael@master ~]$ MYNAME=kitty
[michael@master ~]$ echo $MYNAME
kitty
[michael@master ~]$ readonly MYNAME
[michael@master ~]$ MYNAME=world
bash: MYNAME: readonly variable

使用unset 就可以将变量进行删除。注意,不能删除只读变量

[michael@master ~]$ ADDR='北京'
[michael@master ~]$ echo $ADDR
北京
[michael@master ~]$ unset ADDR
[michael@master ~]$ echo $ADDR
                                               <==此时,变量ADDR就被删除了,所以为空
[michael@master ~]$ 

附加:一组快捷键

组合键 功能
ctrl+u    /   ctrl+k 删除光标前所有的字符 /删除光标后所有的字符
ctrl+a    /   ctrl+e 让光标移动到命令串的最前端 /让光标移动到命令串的最后端

4、环境变量

环境变量,可以让我们更方便的在系统上作业,提高我们的工作效率。那么如何查看Linux系统下的环境变量呢?我们可以通过env和export这两个指令来查询系统上默认的环境变量:

[hyxy@master ~]$ env
HOSTNAME=master                                <==  主机名称
SHELL=/bin/bash                                     <==  shell的种类
TERM=xterm                                            <==  终端使用的环境
HISTSIZE=1000<==记录指令的条数
...........................
USER=hyxy                                               <==  用户名
............................
USERNAME=hyxy
PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hyxy/bin   <==path环境变量
MAIL=/var/spool/mail/hyxy                        <==  用户使用的mailbox位置
PWD=/home/hyxy                                     <==     当前用户的主目录
LANG=zh_CN.UTF-8                                <==   语言
GDM_LANG=zh_CN.UTF-8
HOME=/home/hyxy                                   <==   主目录
LOGNAME=hyxy                                       <==  登录名称
OLDPWD=/home/hyxy/桌面   
_=/usr/bin/env                                            <==   刚刚执行完的指令的返回值

export命令下的显示,我就不给大家看了,你们自行测试吧。

还有另外一个命令set,这个命令会将当前shell的所有变量都显示出来,包含环境变量、接口变量及其用户自定义的变量。在这里我不做显示了,仅仅介绍几个有意思的变量

PS1   :命令提示字符变量。当我们每次回车执行某一个命令后,最后还是要显示命令提示字符的,这个时候就会读取变量PS1,然后按照设置的格式进行显示。我们来看看系统默认的PS1的值:PS1='[\u@\h \W]\$ '按照这个格式,就显示如下:

[hyxy@master ~]$            <==这玩意就是命令提示字符

常用的格式字符有:

\u  :当前用户的账号名称,如:hyxy
\h  :主机名全称的第一个单词,单词以点(.)作为分隔符
\H :主机名全称
\w:完整的工作目录名称,以绝对路径的形式显示,不过主目录会以~的形式显示
\W:只显示最后一个目录名称
\d:时间显示,按照【星期 月 日】的日期格式显示,如“六 12月 29”
\A:时间显示,按照24小时制的【HH:MM】显示
\@:时间显示,按照12小时制的【am/pm】显示  如"11:43 上午"
\#:当前窗口下达的第几个命令
\$:提示符,root用户显示 #,其他用户显示$

应用案例1:

[hyxy@master ~]$ PS1='[\u@\h \w \@ #\#]\$ '
[hyxy@master ~ 11:47 上午 #24]$                  <==24是指第24个指令

应用案例2:

[hyxy@master sysconfig]$ PS1='[\u@\h \w \A]\$ '
[hyxy@master /ect/sysconfig 11:53]$ 

$变量:也是一个变量。返回当前进程的PID

[hyxy@master ~]$ echo $$
2857

?变量:返回上一个命令的退出状态。 0表示成功退出。1~255,表示退出出现错误。

[hyxy@master ~]$ nihao
bash: nihao: command not found
[hyxy@master ~]$ echo $?
127                                           <==错误代码 127
[hyxy@master ~]$ find -name
find: 遗漏“-name”的参数
[hyxy@master ~]$ echo $?
1                                               <==错误代码 1

5、环境变量与自定义变量的区别

使用了env和set两个指令后,你们应该知道什么是环境变量和自定义变量了吧。那么环境变量和自定义变量到底有什么差别呢?其实差别就在于是否可以被子程序能继续使用

那么什么是父程序和子程序呢?

当我们使用命令界面进行登录后,就会获取对应的bash进行工作。这个bash是独立的程序,我们在这个bash下,可以使用任意命令进行其他任务,而每个命令就是一个程序,这些程序都是由bash这个独立的程序启动的。bash就是父程序,命令程序就是子程序。比如我们在bash程序中,再次输入bash这个命令,就会开启一个新的子程序。

[hyxy@master ~]$ ADDR='上海'
[hyxy@master ~]$ echo $ADDR       
上海                                          <==当前程序中,可以使用自定义变量,有输出
[hyxy@master ~]$ bash           <==使用bash 开启一个新的子程序
[hyxy@master ~]$ echo $ADDR
                                                 <==子程序中,自定义变量失效
[hyxy@master ~]$ 

如何将自定义变量转成环境变量呢?那就是export命令的工作了。很简单,只需要使用export命令来导出,输出自定义变量
格式:export   变量名

[hyxy@master ~]$ echo $$
4300                                       <==当前进程的PID
[hyxy@master ~]$ ADDR='长春'
[hyxy@master ~]$ echo $ADDR
长春
[hyxy@master ~]$ export ADDR      <==转成环境变量
[hyxy@master ~]$ bash                   <==开启一个子程序
[hyxy@master ~]$ echo $$
4341                                                 <==子程序的的PID
[hyxy@master ~]$ echo $ADDR
长春                                                  <==有输出
[hyxy@master ~]$ bash                    <==再开启一个子程序
[hyxy@master ~]$ echo $$
4354                                                  <==另外一个子程序的的PID
[hyxy@master ~]$ echo $ADDR
长春                                                    <==有输出

6、read命令

在这之前,变量的值都是直接被指定的。而read命令,可以让变量接收键盘录入的数据。这就好比Java语言的Scanner类型,可以开启键盘录入功能。read功能常用与shell script中。

格式:[hyxy@master ~]$   read   [选项]   variable

常用选项介绍:

  • -p:用于指定提示信息
  • -n:规定录入字符串长度,达到此长度,自动结束
  • -t :对录入进行时间限制,后面是秒数
  • -s:隐藏输入的数据

应用案例1

[hyxy@master ~]$ read -p "请输入用户名:" username
请输入用户名:hyxy
[hyxy@master ~]$ echo $username
hyxy

应用案例2

[hyxy@master ~]$ read -p "请输入密码:" -s pass
请输入密码:
[hyxy@master ~]$ echo $pass
1234

-------------------------------------------------------如有疑问,留言必答---------------------------------------------------

猜你喜欢

转载自blog.csdn.net/Michael__One/article/details/85269078