BASH是什么?
要了解BASH是什么,首先得知道shell,
应用程序是发展在操作系统上的,用户可以通过应用程序来指挥内核,让内核完成我们所需要的硬件任务,我们知道应用程序其实是在最外层,就如同鸡蛋的壳一样,因此shell就被成为壳程序那么这个壳程序的作用是什么呢,能够操作应用程序的软件都能够被称为壳程序。
狭义的壳程序是指命令行方面的软件比如这次我们要学习的BASH
广义的壳程序则包括图形用户界面模式的软件比如X Window
Linux使用的是什么shell?
我们经常听的Bourne Shell(sh),在Sun里头默认的C Shell,商业上常用的K Shell,还有TCSH等,每一中Shell都各有其特点。至于Linux使用的版本称为[Bourne Again Shell](简称bash),这个Shell是Bourne Shell的增强版本,也是基准于GNU的架构发展出来的。
那么目前我们linux有多少我们可以使用的shell呢,可以检查一下/etc/shells这个文件,至少就有下面这几个可以用的shells
/bin/sh(已经被/bin/bash所代替)
/bin/bash(就是Linux默认的shell)
/bin/ksh(Kornshell由AT&T Bell lab.发展出来的,兼容于bash)
/bin/tcsh(整合C Shell,提供更多的功能)
/bin/csh(已经被/bin/tcsh所替代)
/bin/zsh(基于ksh发展出来的,功能更强大的shell)
Linux默认的Shell使用的是bash。系统上合法的shell要写入/etc/shells这个文件,因为系统某些服务在运行过程中,会检查用户能够使用的shells,而这些shell的查询就是借助/etc/shells这个文件。
BASH的优点是什么
1 历史命令:
我们只需要在命令行按上下键就可以找到前后一个输入的命令,在很多的Linux发行版,默认的命令记录可以达到1000个,几乎你曾经执行的命令都被记录下来了,这多莫命令记录在哪里,在你家目录内的.bash_history.
不过需要留意的是该文件记录的是前一次登录所执行的命令,而这一次登录所执行的命令都被缓存在内存中,当你注销系统后,该命令才会记录到.bash_history当中
2 命令与文件补全功能(Tab按键的好处):
经常在bash环境中使用Tab是个好习惯,因为至少可以少打很多字,并且确定输入的数据是正确的。使用Tab按键实际依据Tab接在命令后或参数后而有所不同。
Tab接在一串命令的第一个字的后面,则为命令补全
Tab接在一串命令的第二个字的后面,则为文件补全
在bash shell下面多按几次Tab会有很大的便捷哟。
3 命令别名设置功能(alias)
Linux中命令的别名使用的是alias。在命令行输入alias就可以知道目前的命令别名。可以通过命令来设置别名:
alias lm='ls –al'
4 程序化脚本(shellscript)
Linux下面的shell则发挥更为强大的功能,可以将你平时管理系统常需要执行的连续命令写成一个文件,该文件并且可以通过交互式的方式来进行主机的检测工作,也可以借由shell提供的环境变量及相关命令来进行设计,这几乎就是一个小型的程序语言了。
5 通配符(Wildcard)
除了完整的字符串外,bash还支持许多的通配符来帮助用户的查询与命令执行。利用通配符,可以加快用户的操作。
比如你想知道/usr/bin下面有多少以X开头的文件吗,就可以使用 ls -l/usr/bin/X*,就可以知道。
查询命令是否为Bash shell的内置命令:type
为了方便shell的操作,bash已经内置了很多命令,如cd,umask等。
可以利用type来查看命令是否内置在bash内。
type [-tpa] name
选项与参数:
不加任何参数时,type会显示出name是外部命令还是bash的内置命令
-t:当加入-t参数时,type会将name以下面这些字眼显示出它的意义:
file:表示为外部命令
alias:表示该命令为命令别名所设置的名称
builtin:表示该命令为bash内置的命令功能
-p:如果后面接的name为外部命令时,才会显示完整文件名
-a:会有PATH变量定义的路径中,将所有含name的命令都列出来,包含alias
例:
dmtsailstudy ~]$ type cd
cd is a shell builtin cd是shell的内置命令
通过type这个命令可以知道每个命令是否是bash的内置命令。由于利用type找到后面的名称时,如果后面接的名称并不能以执行文件的状态被找到,则该名称是不会被显示出来的。即type主要找出执行文件而不是一般文件名。type也可以用来作为类似which命令的用途了。
命令的执行与快速编辑
当输入命令一行放不下,我们要输入\Enter,其中Enter键时紧跟着反斜杠\的,中间没有其他字符。因为\仅转义紧接着的下一个字符而已。如果顺利转义Enter后,下一行最前面就会出现>的符号,可以继续输入命令。
另外,当你所需要执行的命令特别长,或是你输入了一串错误的命令时,你想要快速的将这段令整个删除,一般来说, 我们都是使用删除键。有没有其他的快速组合键可以使用呢?有如下:
[ctrI]+u/(ctrl]+k
分别是从光标处向前删除命令串(ctrl+u)及向后删除命令串(ctrl+k))
[ctr]+a/ctrl]+e
分别是让光标移动到整个命令事的最前面([ctrl]+a) 或最后面([ctrl]+e)
shell的变量功能
变量定义:
变量就是以一组文字或符号等,来替换一些设置或一些保留的数据,例如:我设置了[myname ]就是[ VBird],所以当你读取myname这个变量就会知道,那就是Vbird,那么如何显示变量?这就需要使用到echo这个命令。
变量的显示与设置:echo,unset
变量内容的显示使用echo命令。echo命令显示变量,但是在变量被显示时,前面必须加上字符$才行。
echo $variable
echo $PATH
echo ${
PATH}
推荐最后一种方式哈
设置与修改变量
设置变量用等号=连接变量与它的内容即可。
dmtsailstudy ~]$ echo ${
myname}
显示空,因为没有变量,为空
dmtsailstudy ~]$ myname=VBird
dmtsailstudy ~]$ echo $myname
VBird
在bash当中,当一个变量名称尚未被设置时,默认的内容是空的。同时在变量的设置时,需要符合某些规定,否则会设置失败,具体规则如下:
变量设置规则
1 变量与变量内容以一个等号=来连接,如下所示:
myname=yzhang
2 等号两边不能直接接空格符,如下所示为错误的:
myname = VBird 或 myname=VBird Tsai
3 变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:
2yz=VBird
4 变量内容若有空格可使用双引号"或单引号’将变量的内容结合起来,但双引号内的特殊字符如$等,可以保持原本的特性,如:
var=“lang is $LANG”,则echo $var,可得"lang is zh_CN.UTF-8"
5 单引号内的特殊字符进位一般字符(纯文本),如下所示:
var=‘lang is $LANG’,则echo $var,可得lang is $LANG
6 可用转义字符 \ 将特殊符号(如Enter,$,\,空格符 ,’ 等)变成一般字符
myname=VBird\ Tsai
7 若该变量为了增加变量内容时,则可用$ 变量名称 或 ${变量}累加内容,如下所示:
PATH=${PATH}:/home/bin
8 若该变量需要在其他子进程执行,则需要以export来使变量变成环境变量:
export PATH
9 取消变量的方法使用“unset变量名称”,如取消myname的设置:
unset myname
子进程:在目前这个shell情况下,去打开另一个新的shell,新的那个shell就是子进程。在一般状态下,父进程的自定义变量无法在子进程内使用。但是通过export将变量变成环境变量后,就能够在子进程下面使用。
变量设置中,要注意一些特殊符号的使用,如单引号,双引号,转义字符,$,反单引号等。
在变量设置当中,单引号与双引号的用途有何不同?
单引号与双引号的最大不同在于双引号仍然可以保有变量的内容,但单引号内仅能是一般字符,而不会有特殊符号。即单引号中,$变量将失去原有的变量内容,仅为一般字符的显示类型而已。
例
[dmtsailstudy ~]$ name=VBird
[dmtsailstudy ~]$ echo $name
[dmtsai@study ~]$ myname="$name its me"
[dmtsai@study ~]$ echo $myname
[dmtsai@study ~]$ myname= ' $name its me'
(dmtsai@study ~]$ echo $myname
Sname its me
环境变量功能
环境变量可以帮助我们达到很多功能,包括主文件夹的变化,提示符的显示,执行文件查找的路径等。我们可以用env和export命令来查找默认的环境变量
HOME:代表用户的主文件夹
SHELL:告知目前环境使用的shell是哪个程序。Linux默认使用/bin/bash
HISTSIZE:历史命令有关,曾经执行过的命令可以被系统记录下来,而记录的条数由该值设置
MAIL:在使用mail命令收信时系统会去读取的邮件信息文件(mailbox)
PATH:执行文件查找路径,目录与目录中间以冒号(:)分割,由于文件的查找时依序由PATH的变量内的目录来查询,所以目录的顺序也比较重要。
LANG:语序数据。它会主动去分析语系数据文件,如果发现有它无法解析的编码语系,可能会产生错误。
RANDOM:随机数变量。用于获取随机数值。随机数生成器是/dev/random文件,利用这个随机文件相关的变量($RANDOM)来随机取得随机数值。在BASH下,RANDOM变量的内容介于0-32767之间,只要ehco $RANDOM,则系统会主动随机取出一个介于0-32767的数值。取0-9之间的数值,使用如下命令:
dmtsailstudy ~]$ declare –I number=$RANDOM*10/32768;ehco $number
用set查看所有变量(环境变量与自定义变量)
bash可不只有环境变量,还有一些与bash操作接口有关的变量,以及用户自己定义的变量存在。查看变量使用set。set除了环境变量之外,还会将bash内的其他变量全部显示出来。
一般来说,不论是否为环境变量,只要跟我们目前这个shell的操作接口有关的变量,通常会被设置为大写字符,即基本上Linux默认情况下,使用{大写的字母}来设置的变量一般为系统内需要的变量。
变量键盘的读取、数组与声明:read,array,declare
read
要读取来自键盘输入的变量,就是用read这个命令。此命令常被用在shell scripts的编写当中。
read [-pt] variable
参数:
-p:后面可以接提示符;
-t:后面可以接等待的秒数。不会一直等待用户。让用户由键盘输入内容,将该内容变成atest的变量
[dmtsai@study ~]$read attest
This is a test 输入
[dmtsai@study ~]$echo $attest
This is a test
read之后不加任何参数,直接加上变量名称,会主动出现一个空白行,等待输入。如果加上-t后面接描述,则在规定的时间内为输入,该命令将自动略过。加上-p是输入光标前的提示符。
declare/typeset
declare与typeset是一样的功能,就是声明变量的类型。使用declare后面并没有接任何参数,那么bash会主动将所有的变量名称与内容全部调出来,就好像使用set一样。
declare[-aixr] variable
参数:
-a:将后面名为variable的变量定义成为数组(array)类型
-i:将后面名为variable的变量定义为整数数字(integer)类型
-x:用法与export一样,就是将后面的variable变成环境变量
-r:将变量设置成为readonly类型,该变量不可被更改内容,也不能重设。
[dmtsai@study ~]$sum=100+300+50
[dmtsai@study ~]$echo $sum
100+300+50
[dmtsai@study ~]$declare –i sum=100+300+50
[dmtsai@study ~]$echo $sum
450
默认情况下,bash对于变量的几个基本定义如下:
1 变量类型默认为“字符串”,所以若不指定变量类型,则1+2为一个字符串,而不是计算式,所以上述第一个执行结果为不会计算
2 bash环境中的数值运算,默认最多仅能到达整数类型,所以1/3结果为0
3 如果非字符串类型的变量,就有进行变量的声明才行。
declare是个很有用的功能,当使用数组功能时,它可以帮助声明数组的属性。不过数组在shell script中比较常用。不过如果不小心将变量设置为只读,通常要注销登录才能复原该变量的类型。
数组(array)变量类型
在bash中,数组的设置方式如下:
var[index]=context,即有一个数组名为var,数组内容…。bash提供一维数组。
设置数组变量
[dmtsai@study ~]$var[1]="small"
[dmtsai@study ~]$var[2]="big"
[dmtsai@study ~]$echo "${var[1]}, ${var[2]}"
数组变量的读取,一般建议直接以${数组}的方式来读取,会比较正确无误。
与文件系统及程序的限制关系:ulimit
bash是可以限制用户的某些系统资源的,包括可以打开的文件数量,可以使用的CPU时间,可以使用的内存总量等。具体使用ulimit命令:
ulimit [-SHacdfltu] [配额]
参数:
-H:hard limit,严格的设置,必定不能超过这个设置的数值
-S:soft limit,警告的设置,可以超过这个设置值,但是若超过则有警告信息。在设置为100,则可以用到90,但介于80~100之间时,系统会有警告信息通知。
-a:后面不接任何参数,可以列出所有的限制额度
-c:当某些进程发生错误时,系统可能会将该进程在内存中的信息写成文件(排错用),这种文件被称为内核文件(core file),此为限制每个内核文件的最大容量
-f:此shell可以创建的最大文件容量(一般可能设置为2GB)单位为KB
-d:进程可使用的最大断裂内存容量
-l:可用于锁定(lock)的内存量
-t:可使用的最大CPU时间(单位为秒)
-u:单一用户可以使用的最大进程数量
单一文件系统能够支持单一文件大小与block的大小有关。用ulimit来限制用户可以创建的文件大小。具体使用ulimit –f命令设置。若想复原ulimt的设置,简单方法是注销重新登录,否则重新设置ulimit才行。一般用户如果ulimit设置了文件的大小,那么它只能继续减小文件容量,不能增加文件容量。
命令别名与历史命令
命令别名设置:alias,unalias
通过设置别名,可以在一些命令中增设默认的选项可以预防一不小心误删文件的情况发生。在查询隐藏文件时,需要列出于一页一页的翻看,则需执行ls –all more这个命令。可以使用如下命令
alias lm=‘ls –l | more’
此时会多出一个命令lm,其执行ls –all more。不过注意:alias定义规则与变量的定义规则几乎相同,所以要在alias后面加上你的{“别名”=’命令参数…’}。此时能够比较方便使用命令。
root删除数据,不小心,可能导致误删,故可以设置别名,其中使用rm的-i参数,具体如下:
alias rm=’rm –i‘
获取目前系统所具有的别名,使用alias命令即可。
取消别名,使用unalias命令。
取消刚才的lm命令,使用如下:
unalias lm
命令别名与变量不同:命令别名是新创建一个新的命令,可以直接执行该命令,至于变量则需要使用类似echo的命令才能够调用变量的内容。
历史命令
查询历史命令,使用history命令。
参数:
-n:数字,是要列出最近的n条命令行的意思
-c:将目标的shell中的所有history内容全部消除
-a:将目前新增的history命令新增加到histfiles中,若没有增加histfiles,则默认写入~/.bash_history
-r:将histfiles的内容读到目前这个shell的history记忆中
-w:将目前的history记忆内容写入histfile记忆
[dmtsai@study ~]$ history 列出目前内存的所有history记忆
[dmtsai@study ~]$ history 3 列出目前最近的三条数据
[dmtsai@study ~]$ history –w 立刻将目前的数据写入histfile当中
[dmtsai@study ~]$ echo $HISTSIZE
1000
当以bash登录Linux主机后,系统会主动由家目录的~/.bash_history读取以前曾经下过的命令,那么~./bash_history会记录的数据就与bash的HISTSIZE这个变量设置值有关
假设登录主机后,共执行100次命令,等注销时,系统将101-1100这1000笔的历史命令重新更新到~/.bash_history当中。也就是说历史命令在我注销时,会将最近的HISTSIZE条记录到我的记录文件当中。
可以用history –w强制立刻写入。更新:因为~/.bash_history记录的条数永远都是HISTSIZE,旧的信息会被主动去掉。仅仅保留最新的。
!number 执行第几条命令的意思
!command 最近的命令向前搜索命令串开头为command的那个命令,并执行
!! 执行上一个命令
[dmtsai@study ~]$ !66 执行第66条的命令
[dmtsai@study ~]$ !! 执行上一条的命令
[dmtsai@study ~]$ !al 执行最近的以al开头的命令
同一账号同时多次登录的history写入问题
多个bash执行命令时,最后注销的那个bash才会是最后写入的数据。为了避免之一问题,可以考虑单一bash登录,再用任务管理来切换不同的工作。这样才能够将所有曾经执行过的命令记录下来,才方便将来系统管理员进行命令的debug。
路径与命令查找顺序
基本上命令运行的顺序可以这样看:
1 以相对/绝对路径执行命令,如/bin/ls,或/.ls
2 有alias找到该命令来执行
3 由bash内置的(builtin)命令来执行
4 通过$PATH这个变量的顺序找到第一个命令来执行
例
设置echo的命令别名为echo-n,然后在查看echo执行的顺序
[dmtsai@study ~]$ alias echo=’ehco –n’
[dmtsai@study ~]$ type –a echo
echo is aliased to 'echo -n'
echo is a shell builtin
echo is /user/bin/echo
看很清楚吧!
先alias(别名),再builtin(内置),在$PATH(环境变量)
通配符与特殊符号
符号 | 意义 |
---|---|
* | 代表0个到无穷多个任意符 |
? | 代表一定有一个任意字符 |
[] | 同样代表一定有一个在中括号内的字符(非任意字符)。如[abcd]代表一定有一个字符,可能是a,b,c,d这四个任何一个 |
若括号内的第一个字符为指数符号 ^ ,那表示原始方向,如[^abc]代表一定有一个字符,只要是非a,b,c的其他字符就接受的意思。
例
[dmtsai@study ~]$ ll –d /etc/cron* 找出/etc/下面以cron为开头的文件名,加d是为了显示目录
[dmtsai@study ~]$ ll –d /etc/????? 找出/etc/下面文件名刚好是五个字母的文件名
[dmtsai@study ~]$ ll –d /etc*[0-9]* 找出/etc/下面文件名含有数字的文件名,记得左右两边都需要*
[dmtsai@study ~]$ ll –d /etc/[^a-z]* 找出/etc/下面文件名开头不是为小写字母的文件名,注意左边没有*
[dmtsai@study ~]$ cp –a /etc/[^a-c]* /tmp 找出/etc/下面文件名开头为非小写字母的文件名,并将其复制到/tmp下
bash还有一些特殊的符号
符号 | 意义 |
---|---|
# | 批注符号,这个最常被使用在script当中,视为说明。其后的数据均不执行 |
\ | 转义符号,将“特殊字符或通配符”还原成一般字符 |
’ | ’ |
; | 连续命令执行分割符,连续命令的界定(注意与管道命令并不相同) |
~ | 用户主文件夹 |
$ | 使用变量前导符,即是变量之前需要加的变量替代值 |
& | 作业控制(job control),将命令变成背景下工作 |
! | 逻辑运算意义上的非的意思 |
/ | 目录符号,路径分割的符号 |
>,>> | 据流重定向,输出导向,分别是“替换”和“累加” |
<,<< | 数据流重定向,输入导向 |
‘ ’ | 单引号,不具有变量置换的功能 |
“ ” | 具有变量置换的功能 |
|
两个 ` 中间为可以执行的命令,也可以使用$() |
( ) | 中间为子shell的起始与结束 |
{ } | 在中间为命令块的组合 |
以上为bash环境中常见的特殊符号。理论上,文件名尽量不要使用上述的字符。
未完代续…