学习Bash相关知识

来源:互联网 发布:知乎产品分析报告 编辑:程序博客网 时间:2024/04/30 15:35

第十一章 总结

认识bash这个shell

管理整个计算硬件的其实是操作系统的内核(kernel),这个内核是需要被保护的,所以一般用户只能通过shell来跟内核通信,以让内核达到所想要达到的工作。

如果要计算机来传输音乐时,需要的东西如下:

²  硬件:此时需要的硬件为”声卡芯片”这个配备,否则不会发出声音。

²  内核管理:操作系统的内核可以支持这个芯片组,当然还需要提供芯片的驱动程序

²  应用程序:需要用户输入发生声明的命令。

硬件如何知道执行命令?此为Kernel(内核)的控制工作。即必须通过shell将输入的命令与内核通信,好让内核控制硬件来正确无误的工作。

操作系统其实是一组软件,由于这组软件在控制整个硬件与管理系统的活动监测,如果这组软件能被用户随意操作,若用户应用不当,将会整个系统崩溃。操作系统管理的就是整个硬件功能,故不能够随便被一些没有管理能力的终端用户随机使用。

用户让操作系统工作,需要通过应用程序来指挥内核,让内核达到所需要的硬件任务。这个应用程序称为shell。

Shell功能:只是提供用户操作系统的一个接口,因此这个shell需要可以调用其他软件才好。

如之前的man,chmod,chown,vi,fdisk,mkfs等命令,都是独立的应用程序,可通过shell(命令行模式)来操作这些应用程序,来让这些应用程序调用内核运行所需的工作。

只要能够操作应用程序的接口都能够被称为shell。狭义的shell指的是命令行方面的软件,包括bash等。广义shell则包括图形界面的软件,因为图形界面其实也能够操作各种应用程序来调用内核工作。

学习命令行界面shell

命令行界面的shell:大家都一样。

远程管理:命令行界面就是比较快。

Linux的管理经常需要远程联机,而联机时命令行界面的传输速度一定比较快,而且不容易出现断线或者是信息外流问题,故shell是值得学习的。学习shell可以让我们更深入了解Linux,同时不用一直操作鼠标。

Linux的shell

如果想要将主机管理好,那么良好的shell编程是一定需要的。

利用shell提供的数据流重定向以及管道命令等,可以将系统日志信息记录在文件中,便于快速查看主机的一些重要信息。

系统的合法shell与/etc/shells功能

Shell具有不同类型,包括BourneShell(sh),Sun里头默认的C Shell,商业上常用的K Shell,还有TCSH等,每一中Shell都各有其特点。Linux使用的版本称为Bourne Again Shell(简称bash),这个Shell是Bourne Shell的增强版本,也是基于GNU的架构发展出来的。

可以查看一下/etc/shells这个文件至少有哪几种shell可以,执行cat /etc/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这个文件。

举例:某些FTP网站会检查用户可用的shell,而如果不想让用户使用FTP之外的主机资源时,可能会给予该用户一些奇怪的shell,让用户无法以其他服务登录主机。这时,就可将那些怪怪的shell写到shell的/etc/shells当中。如/etc/shells里面的/sbin/nologin文件就是奇怪的shell。

登录取得的shell记录在/etc/passwd文件中。

cat /etc/passwd 显示的每行最后一个数据,就是登录后可以取得的默认shell。

bashshell的功能

/bin/bash是Linux默认的shell,bash是GNU计划中重要的工具软件之一,也是Linux版本的标准shell。

bash主要的优点:

²  命令记忆能力

bash比较好的功能是记忆使用过的命令。这个功能比较好用。因为只要在命令行中按上下键就可以找到前/后一个输入的命令。默认的命令记忆功能可以达到1000个。命令记录在主文件夹内的.bash_history中。不过注意:~/.bash_history记录的是前一次登录以前所执行过的命令,而至于这一次登录所执行的命令都被暂存在临时内存中,但成功注销系统后,该命令才会记录到.bash_history当中。

这一功能的最大好处:可以查询曾经做过的操作。可以通过执行的步骤来追踪曾经执行过的命令,以作为排错的工具。

²  命令与文件补全功能(Tab按键的好处)

经常在bash环境中使用Tab是个好习惯,因为至少可以少打很多字,并且确定输入的数据是正确的。使用Tab按键实际依据Tab接在命令后或参数后而有所不同。

Tab接在一串命令的第一个字的后面,则为命令补全

Tab接在一串命令的第二个字的后面,则为文件补全

在bash shell下面多按几次Tab是一个不错的习惯。

²  命令别名设置功能(alias)

Linux中命令的别名使用的是alias。在命令行输入alias就可以知道目前的命令别名。可以通过命令来设置别名:

alias lm=‘ls –al‘

²  作业控制、前台、后台控制(jobcontrol,foreground,backkground)

Linux中使用前台、后台的控制可以让作业进行得更为顺利。作业控制(jobs)的用途则更广,可以让我们随时将工作丢到后台中执行。不用担心Ctrl + C会中断该进程。

程序脚本(shellscript)

在Linux下面的shell script则发挥更为强大的功能,可以将平时管理系统需要执行的连续命令写成一个文件,该文件并且可以通过交互的方式来进行主机的检测工作。可通过shell提供的环境变量及相关命令来进行设计。整个设计下来几乎都是一个小型的程序语言。

通配符(Wildcard)

除了完整的字符串外,bash还支持许多的通配符来帮助用户的查询与命令执行。利用通配符,可以加快用户的操作。

bashshell的内置命令:type

为了方便shell的操作,bash已经内置了很多命令,如cd,umask等。

可以利用type来查看命令是否内置在bash内。

type [-tpa] name

参数:

²  type:不加任何参数时,type会显示出name是外部命令还是bash内置命令

²  -t:当加入-t参数时,type会将name以下面这些字眼显示出它的意义:

file:表示为外部命令

alias:表示该命令为命令别名所设置的名称

builtin:表示该命令为bash内置的命令功能

²  -p:如果后面接的name为外部命令时,才会显示完整文件名

²  -a:会有PATH变量定义的路径中,将所有含name的命令都列出来,包含alias

type ls

type –t ls

type –a ls

type cd

通过type这个命令可以知道每个命令是否是bash的内置命令。由于利用type找到后面的名称时,如果后面接的名称并不能以执行文件的状态被找到,则该名称是不会被显示出来的。即type主要找出执行文件而不是一般文件名。type也可以用来作为类似which命令的用途了。

命令的执行

特别注意:在输入命令时,当一行放不下,需要输入\Enter,其中Enter键时紧跟着反斜杠\的中间没有其他字符。因为\仅转义紧接着的下一个字符而已。如果顺利转义Enter后,下一行最前面就会出现>的符号,可以继续输入命令。

shell的变量功能

变量定义

变量是让某一个特定字符串代表不固定的内容。可以用一个简单的字眼来代替另一个比较复杂的或者是容易变动的数据。最大的好处是方便。

变量的可变性与方便性

变量可以使程序变得简单,从而带来编程等的方便。

影响bash的环境变量

在Linux下面,所有执行都需要一个执行码,当真正以shell来跟Linux通信,是在正确登录Linux之后。此时就有一个bash的执行程序,即真正经过bash来跟系统通信。而进入shell之前,由于系统需要一些变量来提供它数据的访问(或者是一些环境的设置参数),所以就有一些所谓的环境变量需要来读入系统中。这些环境变量如PATH,HOME,MAIL,SHELL等,为了区别于自定义变量的不同,环境变量通常以大写字符来表示。

脚本程序设计的好帮手

如果要写一个大型的script时,有些数据因为可能由于用户习惯不同而有区别,如路径,由于该路径在script被使用在相当多的地方,如果下次换了一台主机,都要修改script里面所有路径,很不方便。如果使用变量,将该变量定义在最前面,后面相关的路径名称都以变量来替代,则只需修改一行就等于修改整篇script,方便地很。良好的编程都会善用变量的定义。

变量:就是以一组文字或符号等,来替代一些设置或者一串保留的数据。

变量的显示与设置:echo,unset

变量内容的显示使用echo命令。echo命令显示变量,但是在变量被显示时,前面必须加上字符$才行。

echo $variable

echo $PATH

echo ${PATH}

变量的显示利用echo能够读出,只需在变量名称前加上$或者是以${变量}的方式显示即可。

设置与修改变量

设置变量用等号=连接变量与它的内容即可。

echo $myname 显示空,因为没有变量,为空

myname=yzhang

echo $myname

在bash当中,当一个变量名称尚未被设置时,默认的内容是空的。另外变量的设置时,需要符合某些规定,否则会设置失败,具体规则如下:

变量设置规则

²  变量与变量内容以一个等号“=”来连接,如下所示:

“myname=yzhang”

²  等号两边不能直接接空格符,如下所示为错误的:

“myname = yzhang”,“myname=yy zhao”

²  变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:

“2yz=yzhang”

²  变量内容若有空格可使用双引号“”“或单引号”’“将变量的内容结合起来,但是

n  双引号内的特殊字符如$等,可以保持原本的特性,如:

”var=“lang is $LANG””,则echo $var,可得“lang isen_US”

n  单引号内的特殊字符进位一般字符(纯文本),如下所示:

”var=‘lang is $LANG’”,则echo $var,可得“lang is$LANG”

²  可用转义字符”\”将特殊符号(如Enter,$,\,空格符,!等)变成一般字符

²  在一串命令中,还需要通过其它的命令提供的信息,可以使用反单引号“’命令‘”或“$(命令)”。特别注意,那是键盘上方的数字键1左边的那个按键,而不是单引号。如想要取得内核版本的设置:

“version=$(uname-r)”再echo $version可得”2-。16.18-128.el5“

²  若该变量为了增加变量内容时,则可用”$变量名称”或${变量}累加内容,如下所示:

“PATH=”$PATH”:/home/bin”

²  若该变量需要在其他子进程执行,则需要以export来使变量变成环境变量:

“export PATH”

²  通常大写字符为系统默认变量,自行设置变量可以使用小写字符,方便判断(纯粹依照用户兴趣与爱好)

²  取消变量的方法使用“unset变量名称”,如取消myname的设置:

unset myname

设置一个变量name,且内容为VBird

12name=VBirid  失败,命名错误

name = VBird  失败,存在空白

name=VBird 成功

设置一个变量,内容为VBird’s name

name=“VBird’s name”  成功

name=‘VBird’s name’  失败,括号不匹配

name=VBIrd\’s\ name  成功

累加PATH变量

PATH=$PATH:/home/yzhang/bin

PATH=”$PATH”:/home/yzhang/bin

PATH=${PATH}:/home/yzhang/bin

将name多出yes

name=$nameyes  错误变量值为$nameyes

name=”$name”yes  成功

name=${name}yes  成功

让name可用在下一个shell程序

name=vBird

bash

echo $name 失败

exit

export name

bash  子进程

ehco $name

exit

子进程:在目前这个shell情况下,去打开另一个新的shell,新的那个shell就是子进程。在一般状态下,父进程的自定义变量无法在子进程内使用。但是通过export将变量变成环境变量后,就能够在子进程下面使用。

进入目前内核模块

cd /lib/modules/`uname –r’/kernel

cd /lib/modules/$(uname –r)/kernel

上述命令可以做了两次操作:

²  先进行反单引号内的操作“uname–r”并得到内核版本

²  将上述结果代入原命令,故最终切换到对应内核版本的kernel目录下。

取消刚才设置的name变量内容,使用如下命令:

unset name

变量设置中,要注意一些特殊符号的使用,如单引号,双引号,转义字符,$,反单引号等。

在变量设置当中,单引号与双引号的用途有何不同?

单引号与双引号的最大不同在于双引号仍然可以保有变量的内容,但单引号内仅能是一般字符,而不会有特殊符号。即单引号中,$变量将失去原有的变量内容,仅为一般字符的显示类型而已。故需小心

命令执行过程中,反单引号 ` 这个符号代表的意义如何?

在一串命令中,在 ` 之内的命令将会被先执行,而其执行出来的结果将作为外部的输入信息。举例:ls –l `locate crontab’,其实质为先以locate将文件名数据列出来,再以ls命令来处理即可。

如有一个常去的工作目录名称为”/cluseter/server/work/Beijing/,如何进行该目录的简化?

利用变量来降低命令执行的错误,方法如下:

work=”/cluseter/server/work/Beijing/”

cd work

当想用其他目录作为模式工作目录时,只要修改work这个变量即可。这个变量也可以在bash的配置文件中直接指定,从而每次登陆只要修改cd $work就能够取到对应的目录来工作。

注意:使用“version=$(uname–r)”来替代version=`uname –r`比较好,因为反单因号很容易打错或看错。

环境变量功能

环境变量可以帮助我们达到很多功能,包括主文件夹的变化,提示符的显示,执行文件查找的路径等。环境变量的查阅使用env和export命令。

用env查看环境变量与常见环境变量说明

列出当前shell环境下的所有环境变量和内容

env

env是environment(环境)的简写,是列出所有的环境变量。如果使用export在也会是一样的内容,不过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之间的数值,使用如下命令:

declare –I number=$RANDOM*10/32768

ehco $number

用set查看所有变量(环境变量与自定义变量)

bash可不只有环境变量,还有一些与bash操作接口有关的变量,以及用户自己定义的变量存在。查看变量使用set。set除了环境变量之外,还会将bash内的其他变量全部显示出来。

一般来说,不论是否为环境变量,只要跟我们目前这个shell的操作接口有关的变量,通常会被设置为大写字符,即基本上Linux默认情况下,使用{大写的字母}来设置的变量一般为系统内需要的变量。

PS1(提示符的设置)

PS1这个东西是命令提示符。每次按下Enter键去执行某个命令后,最后再次出现提示符时,就会主动去读取这个变量值。

PS1中符号意义如下:

²  \d:可显示出星期月日的日期格式,如Mon Feb 2

²  \H:完整的主机名。

²  \h:仅取主机名的第一个小数点之前的名字

²  \t:显示时间,24小时格式 HH:MM:SS

²  \T:显示时间,12小时格式HH:MM:SS

²  \A:显示时间,为24小时格式 HH:MM

²  \@:显示时间,为12小时格式的am/pm 样式

²  \u:目前用户的账号名称

²  \v:BASH的版本信息

²  \W:利用basename函数取得工作目录名称,所以仅会列出最后一个目录名

²  \#:执行的第几个命令

²  \$:提示符,如果是root,提示符为#

CentOS默认的PS1内容[\u@\h\W]\$.

[root@www /home/dmtsai 16:50 #12]# 中的12代表第12次执行的命令

cd /home

PS1=‘[\u@\h \w \A #\#]\$’

$(关于本shell的PID):$本身也是个变量。这个代表是目前这个Shell的线程代号,即所谓的PID(Process ID)。echo $$用来显示PID的号码。

?(关于上个执行命令的回传码)

问号是一个特殊的变量。在bash里面很重要。这个变量是上一个执行的命令所传回的值,重点是上一个执行命令和回传值。当执行某个命令时,这些命令都会回传一个执行后的代码。一般来说,如果成功执行该命令,则会传回一个0值,如果执行过程中发生错误,就会回传一个错误代码。一般以非0值来代替。

ehco $SHELL

echo $?   显示0

12name=yz

echo S?  显示非0值

OSTYPE,HOSTTYPE,MACHTYPE(主机硬件与内核的等级)

计算机CPU主要分为32,64位,其中32位又可分为i386,i586,i686,而64位则称为x86_64。由于不同等级的CPU指令集不太相同,故软件可能会针对CPU进行优化,以求取最佳的软件性能。软件有i386,i686和x86_64之分。目前主流的硬件,几乎都是x86_64的天下。

注意:较高的硬件通常会向下兼容旧有的软件,但较高的软件可能无法在旧机器上面安装。可以在x86_64的硬件上安装i386的Linux操作系统,但是无法在i686的硬件上安装x86_64的Linux操作系统。

export:自定义变量转换成环境变量

环境变量与自定义变量的差异:该变量是否能被子程序所继续引用。

当登录Linux并取得一个bash之后,bash就是一个独立的进程,被称为PID。接下来,在bash下面执行的任何命令都是由这个bash所衍生出来的,那么被执行的命令就被称为子进程。

子进程仅会继承父进程的环境变量,子进程不会继承父进程的自定义变量,所以原本bash中的自定义变量在进入了子进程后就会消失不见,一直到离开子进程并回到原本的父进程后,这个变量才会又出现。

使用export命令可以让自定义的变量继续在子进程中使用。

export 变量名

在引用自己的变量设置后来调用的文件或其他程序,使用export命令,该方法非常适用于shell scripts。如果仅执行export而没有接变量时,此时将会把所有的环境变量显示出来。

将环境变量转成定义的变量,可以使用declare。

影响显示结果的语系变量(locale)

当使用man command的方式去查询某个数据的说明文件时,该说明文件的内容可能会因为使用的语系不同而产生乱码,另外,ls查询文件时,也可能会有乱码出现在时间的部分。这就是语系问题。

目前大多数的Linux版已经都支持日渐流行的各国及地区代码了,也都支持大部分的语系。这有赖于i18n支持的帮助。可以使用locale查询Linux所支持的语系。

locale –a

繁体中文语系至少支持两种以上的编码,一种是目前还很常见的big5,另一中是越来越热门的utf-8。

locale

基本上,可以逐一设置每个与语系有关的变量数据,但事实上如果有其他的语系变量都未设置,且设置了LANG或LC_ALL,则其他的语系变量就会被这两个变量所替代。Linux中LANG变量的设置是主要的设置变量。

如果发生一些乱码的问题,那么设置系统里面保有的语系编码,如en_US或者en_US.utf8等的设置。系统支持的语系种数,可以通过locale命令查看,它列出系统目前Linux主机内保有的语系文件,这些文件都放置在/usr/lib/locale/这个目录中。

整体系统默认的语系定义在/etc/sysconfig/i18n中,可同cat命令查看。

cat /etc/sysconfig/i18n

变量的有效范围

变量也存在作用范围,被export后的变量为环境变量。环境变量可以被子进程所引用,但是其他的自定义变量内容就不会存在于子进程中。环境变量类似于全局变量,自定义变量类似于局部变量。

环境变量的数据可以被子进程所引用,原因是内存配置的关系。理论上是这样的:

²  当启动一个shell,操作系统会分配一记忆块给shell使用,此内存内的变量可以让子进程取用

²  若在父进程利用export功能,可以让自定义变量的内容写到上述的记忆块当中(环境变量)

²  当加载另一个shell时(即启动子进程,而离开原本的父进程了),子shell可以将父shell的环境变量所在的记忆块导入自己的环境变量块当中。

通过以上,可以让某些变量在相关的进程之间存在,以帮助自己更方便地操作环境。但注意:环境变量与bash的操作环境不太一样。如PS1并不是环境变量,但这个PS1会影响到bash的接口(提示符)。

变量键盘的读取、数组与声明:read,array,declare

read

要读取来自键盘输入的变量,就是用read这个命令。此命令常被用在shell scripts的编写当中。

read [-pt] variable

参数:

²  -p:后面可以接提示符;

²  -t:后面可以接等待的秒数。不会一直等待用户。

让用户由键盘输入内容,将该内容变成atest的变量

read attest

This is a test  输入名字

echo $atest 显示变量名

read –p “Please keyin your name:” –t 30named

Yzhang

ehco $named

read之后不加任何参数,直接加上变量名称,会主动出现一个空白行,等待输入。如果加上-t后面接描述,则在规定的时间内为输入,该命令将自动略过。加上-p是输入光标前的提示符。

declare/typeset

declare与typeset是一样的功能,就是声明变量的类型。使用declare后面并没有接任何参数,那么bash会主动将所有的变量名称与内容全部调出来,就好像使用set一样。

declare[-aixr] variable

参数:

²  -a:将后面名为variable的变量定义成为数组(array)类型

²  -i:将后面名为variable的变量定义为整数数字(integer)类型

²  -x:用法与export一样,就是将后面的variable变成环境变量

²  -r:将变量设置成为readonly类型,该变量不可被更改内容,也不能重设。

sum=100+200

echo $sum  不计算

declare –i sum=100+200

echo $sum   计算

默认情况下,bash对于变量的几个基本定义如下:

²  变量类型默认为“字符串”,所以若不指定变量类型,则1+2为一个字符串,而不是计算式,所以上述第一个执行结果为不会计算

²  bash环境中的数值运算,默认最多仅能到达整数类型,所以1/3结果为0

如果非字符串类型的变量,就有进行变量的声明才行。

将sum变成环境变量

declare –x sum

export | grep sum

让sum变成只读属性,不可改动

declare –r sum

sum=testing   报错

让sum变成非环境变量的自定义变量

declare +x sum   取消

declare –p sum   单独列出变量的类型

declare是个很有用的功能,当使用数组功能时,它可以帮助声明数组的属性。不过数组在shell script中比较常用。不过如果不小心将变量设置为只读,通常要注销登录才能复原该变量的类型。

数组(array)变量类型

在bash中,数组的设置方式如下:

var[index]=context,即有一个数组名为var,数组内容…。bash提供一维数组。

设置数组变量

var[1]=”small”

var[2]=”big

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:单一用户可以使用的最大进程数量

列出目前身份的所有限制数据值

ulimit –a

限制用户仅能创立10MB以下的容量文件

ulimit –f 10240

ulimit –a

dd if=/dev/zero of=123 bs=1M count=20   创建20MB文件,失败

单一文件系统能够支持单一文件大小与block的大小有关。用ulimit来限制用户可以创建的文件大小。具体使用ulimit –f命令设置。若想复原ulimt的设置,简单方法是注销重新登录,否则重新设置ulimit才行。一般用户如果ulimit设置了文件的大小,那么它只能继续减小文件容量,不能增加文件容量。

变量内容的删除、替换与替代

变量的内容可以通过删除,替换等来改变其值。

变量内容的删除与替换

变量的内容可以通过简单的几个命令来进行删除。

先让小写path设置得与大写PATH内容相同

path=$PATH

echo $path

删除其中的变量

echo ${path#/*kerberos/bin:}

说明:

${variable#/*Kerberos/bin:} 特殊字体部分是关键字。用在这种删除模式是必须存在的

${variable#/*Kerberos/bin:}这是原本的变量名称,这就填写了path这个变量名称

${variable#/*Kerberos/bin:} 这是重点,代表从变量内容的最前面开始删除,且仅删除最短的那个。

 ${variable#/*Kerberos/bin:}  代表要被删除的部分,#代表由前面开始删除,所以这里便开始由/写起,*代表通配符

要删除前面所有的目录,仅保留最后一个目录

echo ${path#/*:}  由于一个#,故仅删除掉最短的那个

echo ${path##/*:}  ##表示删除最长的那个数据

因为PATH这个变量的内容中,每个目录都以冒号“:”隔开,所以要从头删除掉目录介于斜线(/)到冒号(:)之间的数据。但是PATH中不只一个冒号(:),所以#和##就分别代表:

²  #:符合替换文字的最短的那一个

²  ##:符合替换文件的最长的那一个

删除最后的那个目录,即从”:”到bin为止的字符串

echo ${path%:*bin}

指向保留第一个目录,执行如下命令:

echo ${path%%:*bin}

由于是想要由变量内容的后面向前面删除,而这个变量的内容最后面的结尾是/root/bin,所以可以看到上面删除的数据最终一定是bin,即:*bin其中*代表通配符。

其中的%%的意义与#和##类似。

假设你是root,你的MAIL变量是/var/spool/mail/root,假设你只想保留最后面那个文件名root,前面的目录名称都不要了,如何利用$MAIL变量来完成?

使用如下命令:echo #{MAIL##/*/}

相反,如果想去掉文件名,保留目录的名称,即/var/spool/mail(最短符合的),但假设并不知道结尾的字符,此时可利用通配符来处理:

echo ${MAIL%/*}

将path变量中的sbin替换成大写SBIN

echo ${path/sbin/SBIN}

将所有的sbin替换成大写SBIN

echo ${path//sbin/SBIN}

总结如下:

变量设置方式

说明

${变量 # 关键字}

若变量内容从头开始的数据符合关键字,则将符合的最短数据删除

${变量 ## 关键字}

若变量内容从头开始的数据符合关键字,则将符合的最长数据删除

${变量 % 关键字}

若变量内容从尾向前的数据符合关键字,则将符合的最短数据删除

${变量 %% 关键字}

若变量内容从尾向前的数据符合关键字,则将符合的最长数据删除

${变量/旧字符串/新字符串}

若变量内容符合旧字符串,则第一个旧字符串被新字符串替换

${变量//旧字符串/新字符串}

若变量内容符合旧字符串,则将全部旧字符串替换为新字符串

变量的测试与内容替换

在某些时候,经常需要判断某个变量是否存在,若变量存在,则使用既有的设置,若变量不存在则基于一个常用的设置。

测试一下是否存在username这个变量,若不存在基于username内容为root

echo $username

username=$(username-root)

ehco $username   赋予root

username=“VBird”

username=$(username-root)

ehco $username   未赋予root

上面命令中,重点在于减号– 后面接的关键字。理解如下:

new_var=${old_var-content}  新的变量,主要用来替换旧变量,新旧变量名称经常一样

new_var=${old_var-content}   关键部分,必须存在

new_var=${old_var-content}   旧的变量,被测试的选项

new_var=${old_var-content}   变量的内容,给予未设置变量的内容。

如果username被设置为空字符串,此时可以通过如下,设置username的内容为root:
username=“”

username=$(username-root)

ehco $username   不能设为root

username=$(username:-root)

echo $username   可以设为root

大括号内有没有冒号:的差别很大。加上冒号后,被测试的变量未被设置或者是已被设置为空字符串,都能够用后面的内容来替换与设置。

变量设置方式

Str没有设置

Str为空字符串

Str已设置非为空字符串

var=${str-expr}

var=expr

var=

var=$str

var=${str:-expr}

var= expr

var=expr

var=$str

var=${str+expr}

var=

var=expr

var=expr

var=${str:+expr}

var=

var=

var=expr

var=${str=expr}

var=expr

str=expr

var=

str不变

var=$str

str不变

var=${str:=expr}

var=expr

str=expr

var=expr

str=expr

var=$str

str不变

var=${str?expr}

expr输出值stderr

var=

var=$str

var=${str:?expr}

expr输出值stderr

expr输出值stderr

var=$str

如果旧变量str不存在,要给予新变量一个内容,若旧变量存在,则新变量内容以旧变量来替换,结果如下:

假设str不存在(用unset),然后测试一下减号(-)的用法

uset str; var=${str-newvar}

echo var=”$var”, str=”$str”

执行结果为var=newer, str=   因为str不存在,所以var为newer

若str已存在,测试var变化

str=”oldvar”; var=${str-newvar}

echo var=”$var”, str=”$str”

显示结果,var=oldvar,str=oldvar,因为str存在,故var=str内容

减少的测试并不会影响到旧变量的内容,想要将旧变量内容也一起替换掉,使用等号=。

假设str不存在(用unset),然后测试一下等号(=)的用法

uset str; var=${str=newvar}

echo var=”$var”, str=”$str”

执行结果为var=newer, str= newer   因为str不存在,所以var/str为newer

若str已存在,测试var变化

str=”oldvar”; var=${str=newvar}

echo var=”$var”, str=”$str”

显示结果,var=oldvar,str=oldvar,因为str存在,故var=str内容

如果旧变量不存在是,整个测试就告知我有错误,此时就能够使用问号?:

假设str不存在(用unset),则var的测试结果直接显示无此变量

uset str; var=${str?无此变量 }    因str不存在,输出错误信息

若str已存在,则var的内容会与str相同

str=”oldvar”; var=${str?novar }

echo var=”$var”, str=”$str”

显示结果,var=oldvar,str=oldvar,因为str存在,故var=str内容

基本上这种变量的测试能够通过shell script内的if … then … 来处理。这种变量测试在程序设置中比较容易出现

命令别名与历史命令

命令别名设置: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命令。

history [n]

history [-c]

history [-raw] histfiles

参数:

²  n:数字,是要列出最近的n条命令行的意思

²  -c:将目标的shell中的所有history内容全部消除

²  -a:将目前新增的history命令新增加到histfiles中,若没有增加histfiles,则默认写入~/.bash_history

²  -r:将histfiles的内容读到目前这个shell的history记忆中

²  -w:将目前的history记忆内容写入histfile记忆

列出目前内存的所有history记忆

history

列出目前最近的三条数据

history 3

立刻将目前的数据写入histfile当中

history –w

echo $HISTSIZE

当以bash登录Linux主机后,系统会主动由主文件夹的~/.bash_history读取以前曾经下过的命令,那么~./bash_history会记录的数据与bash的HISTSIZE这个变量设置值有关

假设登录主机后,共执行100次命令,等注销时,系统将101~1100这1000笔的历史命令重新更新到~/.bash_history当中。即历史注销时,将最近的HISTSIZE条记录到文件当中。

可以用history –w强制立刻写入。更新:因为~/.bash_history记录的条数永远都是HISTSIZE,旧的信息会被主动去掉。仅仅保留最新的。

!number

!command

!!

参数:

²  number:执行第几条命令的意思

²  command:最近的命令向前搜索命令串开头为command的那个命令,并执行

²  !!:执行上一个命令

history

!66

!!

!al 执行最近的以al开头的命令

history用途很大,但需要小心,尤其是root的历史记录文件,这是Cracker的最爱。因为不小心root会将很多重要数据在执行的过程中记录在~/.bash_history当中,如果这个文件被解析化,后果不堪设想。history配置!曾经使用过的命令执行是很有效率的一个命令执行方法。

同一账号同时多次登录的history写入问题

多个bash执行命令,最后注销的那个bash才会是最后写入的数据。为了避免之一问题,可以考虑单一bash登录,再用作业控制来切换不同的工作。这样才能够将所有曾经执行过的命令记录下来,才方便将来系统管理员进行命令的调试。

无法记录时间

历史记录有一个问题是不能记录命令执行的时间。1000条历史记录是依序记录的,并没有记录时间。可以通过~./bash_logout来进行history的记录,并加上date来增加事件参数,即可以应用的方法。

bashShell的操作环境

路径与命令查找顺序

基本上命令运行的顺序可以这样看:

²  以相对/绝对路径执行命令,如/bin/ls,或/.ls

²  有alias找到该命令来执行

²  由bash内置的(builtin)命令来执行

²  通过$PATH这个变量的顺序找到第一个命令来执行

设置echo的命令别名为echo-n,然后在查看echo执行的顺序

alias echo=’ehco –n’

type –a echo

执行过程为,先别名,再内置,在环境变量

bash的登录与欢迎信息:/etc/issue,/etc/motd

bash登录时的欢迎信息就是在/etc/issue里面

cat /etc/issue

注意:issue这个文件的内容也是可以使用反斜杠作为变量的调用。

 

Issue内的各代码意义

\d

本地端时间的日期

\l

显示第几个终端机接口

\m

显示硬件的等级(i386,i486,i586,i686,…

\n

显示主机的网络名称

\o

显示domain name

\r

操作系统的版本(相当于uname –r)

\t

显示本地端的时间

\s

操作系统的名称

\v

操作系统的版本

注意:除了/etc/issue之外,还有个/issue.net。这是个提供给talnet的远程登录程序。当使用talnet连接到主机时,主机的登录界面就会显示/etc/issue.net而不是/etc/issue。

如果想让用户登录后取得一些信息,则可将信息加入到/etc/motd里面。方法是执行如下:

vi /etc/motd 编辑,在其中加入想要加入的数据即可。

bash的环境配置文件

配置文件包括全体系统的配置文件以及用户个人偏好文件。想要保存自己的设置,就得要将这些设置写入配置文件中。

login与non-login shell

login shell:取得bash时,需要完整的登录流程,称为login shell。例如要由tty1~tty6登录,需要输入用户的账号与密码,此时取得的bash称为login shell

non-login shell:取得bash接口的方法不需要重复登录的举动,如以X Windows登录Linux后,再以X的图形界面启动终端机,此时那个终端接口并没有需要再次输入账号与密码,那个bash的环境称为non-login shell。你在原本的bash环境下再次执行bash这个命令,同样也没有输入账号密码,那第二个bash(子进程)也是non-login shell。

login与non-login shell存在因为:两个取得bash的情况中,读取的配置文件数据并不一样所致。

login shell读取配置文件如下:

²  /etc/profile:这是系统整体的设置,最好不要修改这个文件;

²  ~/.bash_profile或~/.bash_login或~/.profile:属于用户个人设置,你要更改自己的数据,就写入这里。

/etc/profile(login shell才会读)

这个配置文件可以利用用户的标识符(UID)来决定很多重要的变量数据,也是每个用户登录取得bash时一定会读取的配置文件。故如果想要帮所有用户设置整体环境,就在这里修改。这个文件的变量主要有:

²  PATH:会依据UID决定PATH变量要不要含有sbin的系统命令路径

²  MAIL:依据账户设置好用户的mailbox到/var/spool/mail/账户名

²  USER:根据用户的账户设置此变量内容

²  HISTSIZE:历史记录条数,默认1000

/etc/profile可不止做这些,还会调用外部设置数据。这些数据会依次被调用进来:

²  /etc/inputrc 判断用户有没有自定义输入变量,有/etc/profile会设置INPUTRC/etc/inputrc变量,此文件内容为bash的热键,Tab声音等数据。

²  /etc/profile.d/*.sh  规定了bash操作接口、语系、ll与ls命令的命令别名、vi命令别名、which的命令别名等等

²  /etc/sysconfig/i18n 设置语系的

bash的login shell情况下所读取的整体环境配置文件其实只有/etc/profile,但是它会调用其他配置文件,让bash接口变得友善。

~/.bash_profile(login shell才会读)

在login shell的bash环境中,所读取的个人偏好配置文件其实主要有三个,依次分别如下:

²  ~/.bash_profile

²  ~/.bash_login

²  ~/.profile

其实bash的login shell设置只会读取上面三个文件的其中一个,而读取顺序则是依照上面的顺序。

bash配置文件的读入方式比较有趣,主要是通过一个命令source来读取的。

source:读入环境配置文件的命令

修改配置文件,不注销生效,使用source命令。

source 配置文件名

source ~/.bashrc

. ~/.bashrc

利用source或小数点 . 都可以将配置文件的内容读进目前的shell环境中。

~/.bashrc(no-loginshell会读)

cat~/.bashrc

里面使用了命令别名,调用/etc/bashrc这个文件。此文件定义了bash的下面数据:

²  依据不同的UID规定umask的值

²  依据不同的UID规定提示符(就是PS1变量)

²  调用/etc/profile.d/*.sh的设置

注意:/etc/bashrc是CentOS特有的,其他版本放在不同的文件中。

其他文件配置

²  /etc/man.config:规定了使用man的时候man page的路径到哪里去寻找

²  ~/.bash_hoistory:主要关于历史命令记录信息

²  ~/.bash_logout:记录当注销bash后系统再帮我做完什么操作(清屏,清空暂存盘等)后离开。

终端机的环境设置:stty,set

stty可以帮助设置终端机的输入按键代表意义。

stty [-a]

参数:

²  -a:将目前所有的stty参数列出。

stty –a:列出所有的按键与按键功能

注意:特殊字体的那几个,此外出现^表示Ctrl键。几个重要的代表意义如下:

²  eof:End of file,代表结束输入

²  erase:向后删除字符

²  intr:送出一个interrupt(中断)的信号给目前正在运行的程序

²  kill:删除在目前命令行上的所有文字

²  quit:送出一个quit的信号给目前正在运行的进程

²  start:在某个进程停止后,重新启动它的输出

²  stop:停止目前屏幕的输出

²  susp:送出一个terminalstrp的信号给正在运行的进程

如果想要用Ctrl + h删除字符,可以执行如下:

stty erase ^h

想要恢复利用Backspace删除,则执行

stty erase ^?

bash的终端设置值使用set。

set [-uvCHhmBx]

参数:

²  -u:默认不启用,若启用后,当使用未设置变量时,会显示错误信息

²  -v:默认不启用,若启用后,通讯息被输出前,会显示信息的原始内容

²  -x:默认不启用,若启用后,在命令被执行前,会显示命令内容(前面有++符号)

²  -h:默认启用,与历史命令有关

²  -H:默认启用,与历史命令有关

²  -m:默认启用,与工作管理有关

²  -B:默认启用,与括号[]的作用有关

²  -C:默认不启用,使用>等时,若文件存在时,该文件不会被覆盖。

显示目前所有的set设置值

echo $-

若使用未定义变量时,显示错误信息

set –u

echo $vbirding

执行前,显示该命令

set –x

echo $HOME

Bash默认的组合键

组合按键

执行结果

Ctrl + C

终止目前的命令

Ctrl + D

输入结束(EOF),如邮件结束的时候

Ctrl + M

就是Enter

Ctrl + S

暂停屏幕的输出

Ctrl + Q

恢复屏幕的输出

Ctrl + U

在提示符下,将整行命令删除

Ctrl + Z

暂停目前的命令

通配符与特殊符号

在bash的操作环境中非常有用的功能,就是通配符。

符号

意义

*

代表0个到无穷多个任意符

代表一定有一个任意字符

[]

同样代表一定有一个在中括号内的字符(非任意字符)。如[abcd]代表一定有一个字符,可能是a,b,c,d这四个任何一个

[-]

若有减号在中括号内时,代表在编码顺序内的字符。如[0-9]代表0到9之间所有的数字,因为数字的语系编码是连续的。

[^]

若括号内的第一个字符为指数符号 ^ ,那表示原始方向,如[^abc]代表一定有一个字符,只要是非a,b,c的其他字符就接受的意思。

利用通配符查找字符串

找出/etc/下面以cron为开头的文件名

ll –d /etc/cron*

找出/etc/下面文件名刚好是五个字母的文件名

ll –d /etc/?????

找出/etc/下面文件名含有数字的文件名

ll –d /etc/*[0-9]*

找出/etc/下面文件名开头非为小写字母的文件名

ll –d /etc/[^a-z]*

找出/etc/下面文件名开头为非小写字母的文件名,并将其复制到/tmp下

Cp –a /etc/[^a-c]* /tmp

除了通配符之外,bash环境中的特殊符号还包括以下:

符号

内容

#

批注符号,这个最常被使用在script当中,视为说明。其后的数据均不执行

\

转义符号,将“特殊字符或通配符”还原成一般字符

|

管道(pipe),分割两个管道命令的界定

连续命令执行分割符,连续命令的界定(注意与管道命令并不相同)

~

用户主文件夹

$

使用变量前导符,即是变量之前需要加的变量替代值

&

作业控制(job control),将命令变成背景下工作

逻辑运算意义上的非的意思

/

目录符号,路径分割的符号

>,>>

数据流重定向,输出导向,分别是“替换”和“累加”

<,<<

数据流重定向,输入导向

‘ ’

单引号,不具有变量置换的功能

“ ”

具有变量置换的功能

` `

两个 ` 中间为可以执行的命令,也可以使用$()

( )

中间为子shell的起始与结束

{ }

在中间为命令块的组合

以上为bash环境中常见的特殊符号。理论上,文件名尽量不要使用上述的字符。

数据流重定向

数据流重定向就是将某个命令执行后应该出现在屏幕上的数据传输到其他的地方,如文件或者是设备(如打印机)上。它在Linux的文本模式下非常重要,尤其是想要将某些数据保存下来时。

标准输出流和标准错误输出流

标准输出指的是命令执行所回传的正确的信息,而标准错误输出可理解为命令执行失败后,所回传的错误信息。

标准输出和标准错误输出的数据都是默认输出到屏幕上,可能导致屏幕混乱。想要将二者分开,可以使用数据流重定向功能。数据流重定向可以将标准输出和标准错误输出分别传送到其他的文件或设备去,而分别传送所用的特殊字符,具体如下:

²  标准输入(stdin):代码为0,使用<或<<

²  标准输出(stdout):代码为1,使用>或>>

²  标准错误输出(stderr):代码为2,使用2>或2>>

查看系统根目录/下各目录的文件名、权限与属性,并记录下来

ll

ll / > ~/rootfile

ll ~/rootfile

cat ~/rootfile

上面程序即可做到屏幕上不显示相关信息,信息存储到文件中。

>重定向是,文件创建的方式如下:

²  该文件若不存在,系统会自动将它创建起来;

²  当这个文件存在的时候,那么系统就会先将这个文件内容清空,然后再将数据写入

²  若以>输出到一个已存在的文件中,那个文件就会被覆盖掉。

如果想要将数据累加而不想要将旧的数据删除,则使用两个大于号>>即可。

输出重定向总结如下:

²  1>:以覆盖的方法将正确的数据输出到指定的文件或设备上

²  1>>:以累加的方法将正确的数据输出到指定的文件或设备上

²  2>:以覆盖的方法将错误的数据输出到指定的文件或设备上

²  2>>:以累加的方法将错误的数据输出到指定的文件或设备上

注意:1>>和2>>中间没有空格。

通过下列方法将正确信息与错误信息分开保存

将stdout和stderr分别存在不同的文件夹中

find /home –name .bashrc > list_right2> list_err

上面命令便能够实现将标准输出信息与标准错误信息分开保存

/dev/null垃圾桶黑洞设备与特殊写法

/dev/null可以吃掉任何导向这个设备的信息。

将错误的数据丢弃,屏幕上显示正确的数据

find /home –name .bashrc 2> /dev/null

上面只有stdout输出显示到屏幕上,stderr将被丢弃

将命令的数据全部写入名为list的文件中

find /home –name .bashrc > list 2>list   错误

find /home –name .bashrc > list2>&1   正确

find /home –name .bashrc &>list   正确

第一种错误,原因是由于两条数据同时写入一个文件,又没有使用特殊的语法,此时两条数据可能会交叉写入该文件中,造成次序的错乱。虽然文件会产生,但是数据乱乱的。对于写入同一个文件的特殊语法,可以使用2>&1,也可以使用&>。

标准输入:<或<<

标准输入:就是将原本需要由键盘输入的数据改由文件内容代替。可以利用cat命令看键盘输入。

利用cat命令来创建一个文件的简单流程

cat > catfile(新文件)

输入相关信息,输入完毕后,按下Ctrl + d结束。

cat catfile

由于加入>在cat后,所以那个catfile会被主动创建,而内容就是刚才键盘上面输入的那两行数据。不过,可以利用某个文件的内容来代替键盘的输入。

用stdin替代键盘的输入以创建新文件的简单流程

cat > catfile < ~/.bashrc

ll catfile ~/.bashrc   类似于cp复制一般

<<代表的是结束输入的意思。举例:要用cat直接将输入信息输出到catfile中,且当由键盘输入eof时,该次输入就结束。

cat > catfile << “eof”

输出相关信息 eof表示结束

cat catfile

利用<<右侧的控制字符,可以终止一次输入,而不必输入Ctrl + d来结束。

输出重定向使用情况如下:

²  屏幕输出的信息很重要,而且需要将它存下来的时候

²  后台执行中的程序,不希望它干扰屏幕正常的输出结果时

²  一些系统的例行命令(如写在/etc/crontab中的文件)的执行结果,希望它可以存下来

²  一些执行命令的可能已知错误信息时,想以2>/dev/null将它丢掉时

²  错误信息与正确信息需要分别输出时。

命令执行的判断依据:;,&&,||

当想要用的命令需要一次输入去执行,不想分层执行,有两种方法实现:通过编写脚本shell script去执行,或通过一次输入多重命令实现。

cmd;cmd(不考虑命令相关性的连续命令执行)

例如,向在关机时执行两次sync同步写入磁盘后在shutdown计算机,可以如下:

sync; sync; shutdown –h now

命令与命令中间利用分号 ; 来隔开,这样一来,分号前的命令执行完后就会立刻接着执行后面的命令。

如果前一个命令的执行影响后一个命令的是否执行,此时需要是用&&或||完成。

$?(命令回传码)与&&与||

若前一个命令执行的结果为正确,则在Linux下面会回传一个$?=0的值。其中&&与||命令执行情况如下:

命令执行情况

说明

cmd1&&cmd2

若cmd1执行完毕且正确执行($?=0),开始执行cmd2

若cmd1执行完毕且为错误($?!=0),则cmd2不执行

cmd1||cmd2

若cmd1执行完毕且正确执行($?=0),则cmd2不执行

若cmd1执行完毕且为错误($?!=0),则开始执行cmd2

使用ls查阅目录/tmp/abc是否存在,若存在则用touch创建/tmp/abc/hehe

ls /tmp/abc && touch /tmp/abc/hehe   不能创建

mkdir /tmp/abc

ls /tmp/abc && touch /tmp/abc/hehe   能创建

ll /tmp/abc

测试/tmp/abc是否存在,若不存在则予以创建,若存在就不做任何事件

rm –r /tmp/abc

ls /tmp/abc || mkdir /tmp/abc

ll /tmp/abc

若不清楚/tmp/abc是否存在,但就是要创建/tmp/abc/hehe文件

ls /tmp/abc || mkdir /tmp/abc &&touch /tmp/abc/hehe

Linux下面的命令都是由左往右执行的。

由于命令是一个接着一个去执行的,因此,如果真要使用判断,那么这个&&与||的顺序不能搞错。即为:

command1&& command2 || command3

上面的顺序通常不会改变,因为一般来说,command2与command3会放置肯定可以执行执行成功的命令。

管道命令(pipe)

管道命令与连续执行命令是不一样的。

假如想要知道/etc/下面有多少文件夹,可以利用ls /etc来查阅,不过/etc下面的文件太多,导致一口气将屏幕塞满,不知道前面输出内容,可以通过less命令协助,具体执行如下命令:

Ls –al /etc | less

如此,就可以利用less命令来翻看输出信息,比较方便。其中主要用到了管道命令| 。管道命令| 仅能处理经由前一个命令传来的正确信息,即标准输出的信息,对于标准错误并没有直接处理的能力。

在每个管道后面接的第一个数据必定是命令,而且这个命令必须能够接收标准输入的数据才行,这样的命令才是管道命令,如less,more,head,tail等都是可以接收标准输入的管道命令。至于ls,cp,mv等就不是管道命令。因为ls,cp,mv并不会接收来自stdin的数据。即管道命令主要有两个比较主要注意的地方:

²  管道命令仅会处理标准输出,对于标准错误输出会予以忽略

²  管道命令必须要能够接来自前一个命令的数据成为标准输入继续处理才行。

选取命令:cut,grep

选取命令:就是将一段数据经过分析后,取出所想要的,或者是经由分析关键字,取得所想要的那一行。注意:一般来说,选取信息通常是针对行来分析的,并不是整篇信息分析的。

cut

这个命令可以将一段信息的某一段切出来,处理的信息是以行为单位的。

cut –d ‘分隔符’ –f fields   用于分割字符

cut –c 字符范围

参数:

²  -d:后面接分割字符,与-f一起使用

²  -f:依据-d的分割字符,将一段信息切割成为数据段,用-f取出第几段的意思

²  -c:以字符的单位去除固定字符区间

将path变量去除,找出第五个路径

echo $PATH

ehco $PATH | cut –d ‘:’ –f 5    第五列

echo $PATH | cut –d ‘:’ –f 3,5   第三列和第五列

将export输出的信息取得第12字符以后的所有字符串

export

export | cut –c 12-

用last在显示的登录者的信息中仅留下用户大名

last  last可以输出“账号/终端机/来源/日期时间”的数据,并且是整齐的

last | cut –d ‘ ‘ –f 1

cut主要的用途是将同一行里面的数据进行分解,最常用在分析一些数据或文字数据的时候。有时可以以某些字符当做切割的参数,然后将数据加以切割,以取得所需要的数据。在日志log分析时,此命令较常用,但cut在处理多空格相连的数据时,可能效果不是特别好。

grep

cut是在一行信息当中取出某部分想要的,而grep则是分析一行信息,若当中有我们所需的信息,就将该行拿出来,其语法如下:

grep [-acinv] [--color=auto] ‘查找字符串’filename

参数:

²  -a:将二进制文件以txt文件的方式查找数据

²  -c:计算找到’查找字符串’的次数

²  -i:忽略大小写的不同,所以大小写视为相同

²  -n:顺便输出行号

²  -v:反向选择,即显示出没有‘查找字符串’内容的那一行

²  --color=auto:可以将找到的关键字部分加上颜色显示

将last当中出现root的哪一行取出来

last | grep ‘root’

将没有root的行取出

last | grep –v ‘root’

在last的输出信息中,只要有root就取出,并仅取一列

last | grep ‘root’ | cut –d ‘ ‘ –f 1

取出/etc/man.config内行MANPATH的那几行

grep –color=auto ‘MANPATH’ /etc/man.config

grep是个很好的命令,它支持的语法很多,可以用在正则表达式中,用来处理的数据很多。

排序命令:sort,wc,uniq

sort命令

sort命令,可以帮助我们进行排序,并可以依据不同的数据类型来排序。如数字与文字的排序就不一样。此外排序的字符与语系的编码有关,因此需要排序,建议使用LANG=C来让语系同一,数据排序比较好。

sort [-fbMnrtuk] [file or stdin]

参数:

²  -f:忽略大小写的差异,如A与a视为编码相同

²  -b:忽略最前面的空格符部分

²  -M:以月份的名字来排序,如JAN,DEC等

²  -n:使用纯数字进行排序(默认是以文字类型来排序的)

²  -r:反向排序

²  -u:相同的数据中,仅出现一行代表

²  -t:分割符,默认使用Tab键来分割

²  -k:以哪个区间(field)来进行排序的意思

个人账户记录在/etc/passwd,请将账号进行排序

cat /etc/passwd | sort

/etc/passwd内容是以:来分割的,以第三列排序

cat /etc/passwd | sort –t ‘:’ –k 3

利用last将输出的数据仅任取账号,并加以排序

last | cut –d ‘ ‘ –f 1 | sort

uniq命令

如果排序完成后,想要将重复的数据仅显示一个,做法如下:

uniq [-ic]

参数:

²  -i:忽略大小写字符的不同

²  -c:进行计数

使用last将账号取出,仅取出账号列,进行排序后仅取出一位

last | cut –d ‘ ‘ –f 1 | sort | uniq

想要知道每个用户登录总次数

last | cut –d ‘ ‘ –f 1 | sort | uniq –c

这个命令将重复的东西减少,故可以配置排序的文件处理来减少重复。

wc命令

wc命令用来计算输出信息的整体数据。

wc [-lwm]

参数:

²  -l:仅列出行

²  -w:仅列出多少字(英文单字)

²  -m:多少字符

将/etc/man.config里面到底有多少相关的字、行、字符数

cat /etc/man.config | wc

使用last可以输出登录者,但是last最后两行并非账号内容,如何以一行命令取得这个月份登录系统的总次数。

last | grep [a-zA-Z] | grep –v ‘wtmp’ | wc–l

wc命令在计算文件内容上是非常有用的一个工具组。

双向重定向:tee

tee会同时将数据流送与文件与屏幕(screen):而输出到屏幕是stdout。

tee [-a] file

参数:

²  -a:以累加的方式,将数据加入file当中。

last | tee last.list | cut –d ‘ ‘ –f1

ls –l /home | tee ~/homefile | more

ls –l / | tee –a ~/homefile | more

tee可以让标准输出转存一份到文件内并将同样的数据继续送到屏幕去处理。这样除了可以同时分析一份数据并记录下来之外,还可以作为处理一份数据的中间暂存盘记录只用。

字符转换命令:tr,col,join,paste,expand

tr命令

tr可以用来删除一段信息当中的文字,或者是进行文字信息的替换。

tr [-ds] SET1…

参数:

²  -d:删除信息当中的SET1这个字符串

²  -s:替换掉重复的字符

将last输出的信息中所有的小写字符变成大写字符

last | tr ‘[a-z]’ ‘[A-Z]’

将/etc/passwd输出的信息中的:删除

cat /etc/passwd | tr –d ‘:’

将/etc/passwd转存成dos断行到/root/passwd中,再将^M符号删除

cp /etc/passwd /root/passed &&UNIX2dos /root/passwd

file /etc/passwd /root/passwd

cat /root/passwd | tr –d ‘\r’ >/root/passwd.linux

ll /etc/passwd /root/passwd*

col命令

col [-xb]

参数:

²  -x:将tab键转换成对等的空格键

²  -b:在文字内有反斜杠(/)时,仅保留反斜杠最后接的那个字符

利用cat –A显示出所有特殊按键,最后以col将Tab转成空白

cat –A /etc/man.config

cat /etc/man.config | col –x | cat –A |more

将col的man page转存成为/root/col.man的纯文本文件

man col > /root/col.man

vi /root/col.man

man col | col –b > /root/col.man

col有它的特殊用途,不过很多时候,可以用来进行简单处理,如将Tab按键替换成为空格键。col经常被利用于将man page转存为纯文本文件以方便查阅的功能。

join命令

join是在处理两个文件之间的数据,而且主要是将两个文件当中有相同数据的那一行加在一起。

join [-ti12] file1 file2

参数:

²  -t:join默认以空格分隔数据,并且对比“第一字段”的数据,如果两个文件相同,则将两条数据连成一行,且第一个字段放在第一个;

²  -i:忽略大小写的差异

²  -1:这是数字1,代表第一个文件要用哪个字段来分析

²  -2:代表第二个文件要用哪个字段来分析

用root身份,将/etc/passwd与/etc/shadow相关数据合并成一列

head –n 3 /etc/passwd /etc/shadow

join –t ‘:’ /etc/passwd /etc/passwd

/etc/passewd的第四个字段是GID,GID记录在/etc/group当中的第三个字段,如何整合

head –n 3 /etc/passwd /etc/group

join –t ‘:’ -1 4 /etc/passwd -2 3/etc/group

join处理两个相关数据文件。注意:在使用join之前,所需要处理的文件应该要事先经过排序sort处理。否则有些对比的项目会被忽略。

paste

paste比join简单多,相对于join必须要对比两个文件的数据相关性,paste就直接将两行贴在一起,且中间以[Tab]键隔开。

paste [-d] file1 file2

参数:

²  -d:后面可以接分隔符,默认是以tab来分割的

²  -:如果file部分写成-,表示来自标准输入的数据

将/etc/passwd与/etc/shadow同一行粘贴在一起

paste /etc/passwd /etc/shadow  同行使用tab键分割

先将/etc/group读出(用cat),然后与上面粘贴在一起,去除前三行

cat /etc/group | paste /etc/passwd/ect/shadow -| head –n 3

expand命令

expand主要将Tab键转成空格键

expand [-t] file

参数:

²  -t:后面可以接数字,一般来说,一个Tab按键可以用8个空格键替换。也可以自定义tab键代表多少个字符。

将/etc/man.config内行首为MANPATH的字样取出,仅取出前三个

grep ‘^MANPATH’ /etc/man.config | head –n 3

将上面的所有特殊字符都列出来

grep ‘^MANPATH’ /etc/man.config | head –n 3| cat –A

将Tab按键设置成6个字符

grep ‘^MANPATH’ /etc/man.config | head –n 3| expand –t 6 - | cat –A

expand会自动将tab转成空格键。因为tab键最大的功能是格式排列整齐,转成空格键后,这个空格键也会依据自己的定义来增加大小,并不是一个^|就会换成8个空白。注意:可以使用unexpand命令将空白转成tab键。

切割命令:split

如果有文件太大,导致一些携带式设备无法复制问题。此时可以用split命令。它可以将一个大的文件依据文件大小或行数来切割成效文件。

split [-bl] file PREFIX

参数:

²  -b:后面可接欲切割成的文件大小,可加单位,如b,k,m等

²  -l:以行数来进行切割

²  PREFIX:代表前导符,可作为切割文件的前导文字。

将/etc/termcap分成300KB一个文件

cd temp

split –b 300k /etc/termcap termcap

ll –k termcap*

会产生三个小文件,分别为termcapaa,termcapab,termcappac

将三个小文件合并成一个大的文件

cat termcap* >> termcapback

使用ls –al /输出的信息中,每10行记录成一个文件

ls –al / | split –l 10 – lsroot

wc –l lsroot*

Linux下可以使用split方便的切割文件,使用-bsize可以将一个切割的文件限制其大小,如果是行数的话,那么使用-l line来切割。

参数代换:xargs

xargs:用于产生某个命令的参数。xargs可以读入stdin的数据,并且可以将空格符或断行字符进行分辨,将stdin的数据分割称为arguments。因为以空格符作为分割,所以一些文件名或者其它意义的名词内含有空格,则可能导致误判。

xargs [-0epn] command

参数:

²  -0:如果输入是stdin含有特殊字符,如 ` ,\,空格键等字符时,这个参数可以将它还原成一般字符。这个参数可用于特殊状态。

²  -e:这个是EOF的意思。后面可以接一个字符串,当xargs分析到这个字符串时,就会停止继续工作。

²  -p:在执行每个命令的参数时,都会询问用户的意思

²  -n:后面接次数,每次command命令执行时,要使用几个参数。

将/etc/passwd内的第一列取出,仅取三行,使用finger这个命令将每个账号内容显示出来

cut –d ‘:’ –f 1 /etc/passwd | head –n 3 |xargc finger

与上相同,但执行finger时,要询问用户是否操作。

cut –d ‘:’ –f 1 /etc/passwd | head –n 3 |xargs –p finger

将所有的/etc/passwd内的账号都以finger查阅,但一次仅查阅5个账号

cut –d ‘:’ –f 1 /etc/passed | xargs –p –nfinger

同时,但是当分析lp时就结束这串命令

cut –d ‘:’ –f 1 /etc/passwd | xargs –p –e‘lp’ finger

使用xargs的原始:很多命令其实并不支持管道命令,因此可以通过xargs来提供该命令引用标准输入之用。

找出/sbin下面具有特殊权限的文件名,使用ls –l列出详细属性

find /sbin –perm +7000 | ls –l  不是想要的主要原因是ls不是管道命令

find /sbin –perm +7000 | xargs ls –l   是所想要的

关于减少-的用途

管道命令在bash的连续处理程序中是相当重要的,在log file的分析当中也是相当重要的一环,故需多注意。另外,在管道命令中,经常会使用到前一个命令的stdout作为这次的stdin,某些命令需要用到文件名来进行处理时,该stdin与stdout可以利用减少’-‘来替代。举例如下:

tar –cvf - /home | tar –xvf –

上面的例子即将/home里面的文件打包,但打包的数据不是记录到文件,而是传送到stdout,经过管道后,将tar –cvf - /home传送给后面的tar –xvf -。后面的这个-则是取用前一个命令的stdout,故不需要使用文件了。

重点总结

²  由于内核在内存中是受保护的块,因此我们必须通过Shell将我们输入的命令与kernel通信,好让kernel可以控制硬件来正确无误地工作

²  学习Shell的主要原因有:命令行界面的Shell在各大distribution都一样;远程管理时命令行界面速度较快;Shell是管理Linux系统非常重要的一环,因为Linux内很多控制都是以Shell编写的。

²  系统合法的Shell均写在/etc/passwd的最后一个字段

²  Bash的功能主要有命令编辑功能、命令与文件补全功能、命令别名设置功能、作业控制、前台、后台控制、程序化脚本、通配符

²  type可以用来找到执行命令为何种类型,也可用于与which相同的功能

²  变量就是以一组文字或符号等来替换一些设置或者是一串保留的数据

²  变量主要有环境变量与自定义变量。或称为全局变量与局部变量

²  使用env与export可查看环境变量,其中export可以将自定义变量转成环境变量

²  set可以查看目前bash环境下的所有变量

²  $?也为变量,是前一个命令执行完毕后的回传码。在Linux回传码为0代表执行成功

²  locale可用于查看语系数据

²  可用read让用户由键盘输入变量的值

²  ulimit可用于限制用户使用系统的资源情况

²  Bash的配置文件主要分为login shell与non-loginshell。login shell主要读取/etc/profile与~/.bash_profile,non-login shell则仅读取~/.bashrc

²  通配符主要有*、?、[]等

²  数据流重定向通过>,2>,<之类的符号将输出的信息转到其他文件或设备去

²  连续命令的执行可通过; && || 等符号来处理

²  管道命令的重点是它仅会处理标准输出,对于标准错误输出会予以忽略。管道命令必须能够接收来自前一个命令的数据成为标准输入继续处理才行

²  管道命令主要有cut,grep,sort,wc,uniq,tee,tr,col,join,paste,expand,split,xargs等。

0 0