一、什么是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
-------------------------------------------------------如有疑问,留言必答---------------------------------------------------