有关shell (2)

管 道

将一个程序或命令的输出作为另一个程序或命令的输入,有两种方法,一种是通过一个临时文件将两个命令或程序结合在一起,例如上个例子中的/tmp/dir文件将ls和wc命令联在一起;另一种是Linux所提供的管道功能。这种方法比前一种方法更好。

管道可以把一系列命令连接起来,这意味着第一个命令的输出会作为第二个命令的输入通过管道传给第二个命令,第二个命令的输出又会作为第三个命令的输入,以此类推。显示在屏幕上的是管道行中最后一个命令的输出(如果命令行中未使用输出重定向)。

通过使用管道符“|”来建立一个管道行。用管道重写上面的例子:

$ ls /usr/bin|wc -w

1789

再如:

$ cat sample.txt|grep "High"|wc -l

管道将cat命令(列出一个文件的内容)的输出送给grep命令。grep命令在输入里查找单词High,grep命令的输出则是所有包含单词High的行,这个输出又被送给wc命令,wc命令统计出输入中的行数。假设sample.txt文件的内容如下:

Things to do today:

Low:Go grocery shopping

High:Return movie

High:Clear level 3 in Alien vs. Predator

Medium:Pick up clothes from dry cleaner

那么该管道行的结果是2。

命令替换

命令替换和重定向有些相似,但区别在于命令替换是将一个命令的输出作为另外一个命令的参数。常用命令格式为:

command1 `command2`

其中,command2的输出将作为command1的参数。需要注意的是这里的`符号,被它括起来的内容将作为命令执行,执行后的结果作为command1的参数。例如:

$ cd `pwd`

该命令将pwd命令列出的目录作为cd命令的参数,结果仍然是停留在当前目录下。

第二十二课 在Bash中的操作      2000年/5月/29日

命令和文件名扩展特性

Bash 命令行具有命令和文件名扩展特性。当输入一个还没完成的命令或文件名时,只需键入Tab键就能激活命令和文件名扩展特性,从而完成该命令的剩余输入。如果 有多个命令或文件的前缀相同,Bash将响铃并等待用户输入足够的字符,以便选择唯一的命令或文件名,如果找到,系统将自动补齐搜索到的命令或文件名,用 户按回车键后,系统将执行这条指令。例如:

$ cat pre <Tab>

$ cat preface

Bash 也能列出当前目录下部分匹配的文件名来完成文件名扩展。如果键入Esc,然后键入?,shell将列出所有与输入的字符串相匹配的文件名。例如下例,在没 有完成的输入后键入Esc ?,shell将列出所有与输入的字符串相匹配的字符串,然后shell回显命令行,根据列出的文件名,可以键入要输入的文件名或按下Tab键来完成文件 名扩展。例如:

$ ls

document docudrama

$ cat doc <ESC ?>

document

docudrama

$ cat docudrama

[例】下面是一个目录包含的文件列表:

Firebird2.7.tgz Firebird.README Firebird2.60.tgz

FireBird Firebird2.60.tgz.README

现在要删除Firebird2.60.tgz.README文件,键入:

$ rm –f Fi<Tab>

系统会发出警报声,并且自动将命令行补全为:

$ rm –f Fire

并等待用户进一步输入文件名的后面部分。现在再键入:

b<Tab>

系统再次发出警报声,并且自动将命令行补全为:

$ rm –f Firebird

并等待用户进一步输入文件名的后面部分。现在再键入:

2.6<Tab>

系统再次发出警报声,并且自动将命令行补全为:

$ rm –f Firebird2.60.tgz

并等待用户进一步输入文件名的后面部分。现在再键入:

.<Tab>

此时命令将被补全为:

$ rm –f Firebird2.60.tgz..README

从上例可以看到,bash总是尽力根据用户输入的信息来补全命令。当无法根据现有信息补全命令时,则提示用户再给出更多的信息,然后再根据用户的提示来进 一步补全命令。作为用户最好是能够一次性给出足够的信息以便于bash进行命令补全;否则多按几次<Tab>,时间也就消耗掉了。

命令行编辑

在Bash中可以对命令行进行编辑,以便用户在执行所键入的命令之前能够修改所键入的命令。如果在键入命令时出现拼写错误,只需在运行所键入的命令之前,使用编辑命令来纠正编辑错误,然后执行它,而不用重新输入整行命令。这个功能对以长路径文件名作参数的命令特别有用。

表10-2是对命令行编辑操作的一个总结。

表10-2 命令行编辑操作

 

命令行编辑操作

功能

Ctrl+b或左箭头键

左移一个字符(移至前一个字符)

Ctrl+f或右箭头键

右移一个字符(移至后一个字符)

Ctrl+a

移至行首

Ctrl+e

移至行尾

Esc b

左移一个单词

Esc f

右移一个单词

Del

删除光标所在处的字符

Ctrl+d

删除光标所在处的字符

BACKSPACE或Ctrl+h

删除光标左边的字符

Ctrl+k

删除至行尾

 

命令历史

在 Bash中,history命令能够保存最近所执行的命令。这些命令的历史记录号从1开始,只有有限个命令可以被保存起来,最多500个,即 history命令的历史记录号缺省值为500。要查看最近执行的命令,只要键入history命令,然后键入回车键,最近执行过的命令即按先后顺序被显 示出来(各条命令前的数字为历史记录号)。

[例】

$ history

1 cp mydata today

2 vi mydata

3 mv mydata reports

4 cd reports

5 ls



所有这些命令都被称为事件(event),一个事件表示一个操作已经发生,即一个命令已被执行。这些事件根据它们被执行的先后顺序用数字标识,这一标识称为历史事件号。最后执行的历史事件的事件号最大。每个事件都可由它的历史事件号或命令的初始字符或字符串等确定。

利用history命令能够查询以前的事件,并可把它们显示到命令行上执行这一事件。最简便的方法就是利用上下箭头键,把先前的事件逐次显示到命令行。这 个操作不需要运行history命令就可以执行。按动一下上箭头键,那么上一次执行的一个事件就将出现在命令行上,再按一下,上一次的前一事件又会出现在 命令行上;按动一下下箭头键,将会使当前事件的下一事件出现在命令行上。

Bash也可以通过键入Esc、Tab键来完成对历史事件的字符扩展。和标准命令行扩展特性一样,键入历史事件的部分字符串,然后键入Esc,再键入 Tab键,与刚才键入的字符串相匹配的历史事件将自动扩展并回显到命令行处。如果不止一个事件与输入的字符串相匹配,就会听到一声响铃,继续键入字符或字 符串,shell将会唯一确定用户所要键入的历史事件。

还有一个查询和执行历史事件的命令——!命令。在!命令后键入与历史事件相关联的字符,这个关联字符可以是历史事件的历史事件号,也可以是该事件的前几个字符。在下面的例子中,查询到历史事件号为3的事件,然后又用其开头的几个字符去匹配,也查询到该命令。

[例】

$ !3

mv mydata reports

$ !mv

mv mydata reports

也可以用一个偏移量(相对于历史事件列表中最后一个事件)来查询历史事件。负的偏移量将从历史事件列表表尾向前偏移。在下面的例子中,历史事件号为2的事 件 “vi mydata”就是用一个负的偏移量查询到的。必须注意的是,这个偏移量是相对于历史事件列表中的最后一个事件的。在本例中,历史事件列表中最后一个事件 是事件5,历史事件列表中第一个事件为1。从历史事件号为5的事件,往前偏移4,即是历史事件号为2的事件。

[例】

$ !-4

vi mydata

如果键入!!,则系统默认为上一事件。下面的例子中,用户在命令行上键入!!命令,系统将执行上一事件:“ls”命令。

[例】

$ !!

ls

mydata today reports

也可以用“模式”来搜索一个历史事件。搜索的“模式”必须用符号“?”括起来。下例是用“模式”“?myd?”来搜索历史事件号为3的历史事件“vi mydata”。

[例】

$ !?myd?

vi mydata

1. 查询历史事件

可以在命令行上编辑历史事件列表中的事件。表10-3列出了查询历史事件列表的各种操作。

表10-3 查询历史事件操作

查询历史事件操作

功能

Ctrl+n或向下光标键

移至历史事件列表中当前事件的下一历史事件

Ctrl+p或向上光标键

移至历史事件列表中当前事件的前一历史事件

Esc <

移至历史事件列表表首

Esc >

移至历史事件列表表尾

!event_num

用历史事件号来定位一个历史事件

!characters

用历史事件的字符前缀来查询一个历史事件

!?pattern

用“模式”来查询历史事件列表中的事件

!-event_num

通过偏移量来定位历史事件
2. 配置history:HISTFILE及HISTSIZE

系统保存的历史事件数被保存在一个特定的系统变量中,这个变量就是HISTSIZE。这个变量的缺省值通常被设置为500。这个值可以被修改。例如:

$ HISTSIZE=10

将HISTSIZE的值重新设置为10。

历史事件被保存在一个文件中,文件名由变量HISTFILE指定。通常这个文件的缺省名是.bash_history。通过给变量HISTFILE赋值,可以指定新的文件名。

[例】

$ echo $HISTFILE

/home/lisa/.bash_history

$ HISTFILE=”/home/lisa/newhist”

$ echo $HISTFILE

/home/lisa/newhist

以上操作先显示变量HISTFILE的值,然后赋予它新的值“/home/lisa/newhist”,以后所有的历史事件将被保存在newhist文件中。

别名

还有一个使工作变得轻松的方法是使用命令别名。命令别名通常是其他命令的缩写,用来减少键盘输入。

命令格式为:

alias [alias-name=’original-command’]

其中,alias-name是用户给命令取的别名,original-command是原来的命令和参数。需要注意的是,由于Bash是以空格或者回车来 识别原来的命令的,所以如果不使用引号就可能导致Bash只截取第一个字,从而出现错误。如果alias命令后面不使用任何参数,则显示当前正在使用的被 别名化的命令及其别名。为命令取的别名在该次登录期间始终有效。如果用户需要别名在每次登录时都有效,那么就将alias命令写到初始化脚本文件中。

[例]如果经常要键入如下的命令,最好为它建立一个别名来减少工作量。

$ cd /usr/X11/lib/X11

假如为这个长命令建立一个名为goconfig的别名,在Bash提示符下键入如下命令:

$ alias goconfig=’cd /usr/X11/lib/X11’

现在,除非您退出Bash,键入goconfig将和原来的长命令有同样的作用。如果想取消别名,可以使用下面的命令:

$ unalias goconfig

这是一些很多人认为有用的别名,可以把它们写入初始化脚本文件中来提高工作效率:

alias ll=’ls –l’

alias log=’logout’

alias ls=’ls –F’

如果您是一名DOS用户并且习惯了DOS命令,可以用下面的别名定义使Linux表现得象DOS一样:

alias dir=’ls’

alias copy=’cp’

alias rename=’mv’

alias md=’mkdir’

alias rd=’rmdir’

注意:在定义别名时,等号两边不能有空格,否则shell不能决定您需要做什么。仅在命令中包含空格或特殊字符时才需要引号。

如果键入不带任何参数的alias命令,将显示所有已定义的别名。

提示符

Bash有两级提示符。第一级提示符是经常见到的Bash在等待命令输入时的情况。第一级提示符的默认值是$符号。如果用户不喜欢这个符号,或者愿意自己定义提示符,只需修改PS1变量的值。例如将其改为:

PS1=”Enter a command:”

第二级提示符是当Bash为执行某条命令需要用户输入更多信息时显示的。第二级提示符默认为>。如果需要自己定义该提示符,只需改变PS2变量的值。例如将其改为:

PS2=”More information:”

上面的两个例子都是设定提示符为静态字符串的情况。其实用户也可以使用一些事先已经定义好的特殊字符。这些特殊字符将使提示符中包含当前时间之类的信息。表10-4列出了最常用的一些特殊字符及其含义。

表10-4 bash提示符常用特殊字符

 

特殊字符

说 明

!

显示该命令的历史编号

#

显示shell激活后,当前命令的历史编号

$

显示一个$符号,如果当前用户是root则显示#符号

/

显示一个反斜杠

d

显示当前日期

h

显示运行该shell的计算机主机名

n

打印一个换行符,这将导致提示符跨行

s

显示正在运行的Shell的名称

t

显示当前时间

u

显示当前用户的用户名

W

显示当前工作目录基准名

w

显示当前工作目录

 

这些特殊字符可以组合起来,为用户提供一些提示符,提供很有用的信息。下面来看几个实际例子:

PS1=”t”

将使提示符变成如下所示:

02:16:15

而 PS1=t

将使提示符变成如下所示:

t

若PS1=”t/”

将使提示符变成如下所示:

02:16:30

该例就是使用两个特殊字符的组合得到的。

控制shell的运行方式

Bash 有一些特殊变量,能控制shell以不同的方式工作。例如,变量noclobber能防止在重定向输出时意外地覆盖一个文件。通过set命令可以设置 noclobber变量的有效或无效。set命令有两个参数:一个是指定变量开(on)或关(off)的选项,一个是特殊变量的变量名。要使某一特殊变量 开(有效),用-o选项,要使其关(无效),用+o选项。例如:

$ set –o noclobber // 使noclobber变量开

$ set +o noclobber // 使noclobber变量关

三个最常用的shell特殊变量有:ignoreeof、noclobber及noglob。

ignoreeof

ignoreeof 变量用来禁止使用ctrl+d来退出shell(ctrl+d不仅用来退出shell,而且可以终止用户直接输往标准输出上的输入。该操作经常在一些 shell实用命令中使用,例如实用命令cat。在这些实用程序操作中,非常容易误操作而意外地退出shell。ignoreeof特殊变量正是用来防止 这种意外的退出。例如:

$ set –o ignoreeof

之后,用户只能用logout或exit命令退出shell。

noclobber

noclobber变量可以在重定向输出时保护已存在的文件,防止被意外地覆盖。在下例中,用户设置noclobber为有效,在重定向时,用户试图去覆盖已经存在的文件myfile,此时系统将返回一个错误信息。

[例]

$ set –o noclobber

$ cat preface>myfile

bash: myfile: cannot overwrite existing file

$

noglob

设置noglob变量后,shell将不扩展文件名中一些特殊的字符或字符串。如字符*、?、[]等将不再作为通配符。如果用户希望列出结尾为?的文件名 answer?,可通过如下步骤:首先,用户使noglob变量为无效,然后再列出文件名。可以看到,目前命令行上的问号?被认为是文件名中的一个字符, 而不再被看作通配符。

$ set –o noglob

$ ls answer?

answer?

子shell与export命令

用户登录到Linux系统后,系统将启动一个用户shell。在这个shell中,可以使用shell命令或声明变量,也可以创建并运行shell脚本程 序。运行shell脚本程序时,系统将创建一个子shell。此时,系统中将有两个shell,一个是登录时系统启动的shell,另一个是系统为运行脚 本程序创建的shell。当一个脚本程序运行完毕,它的脚本shell将终止,可以返回到执行该脚本之前的shell。从这种意义上来说,用户可以有许多 shell,每个shell都是由某个shell(称为父shell)派生的。

在子shell中定义的变量只在该子shell内有效。如果在一个shell脚本程序中定义了一个变量,当该脚本程序运行时,这个定义的变量只是该脚本程 序内的一个局部变量,其他的shell不能引用它,要使某个变量的值可以在其他shell中被改变,可以使用export命令对已定义的变量进行输出。 export命令将使系统在创建每一个新的shell时定义这个变量的一个拷贝。这个过程称之为变量输出。

[例]在本例中,变量myfile是在dispfile脚本程序中定义的。然后用export命令将变量myfile输出至任何子shell,例如当执行printfile脚本程序时产生的子shell。

dispfile脚本程序清单:



myfile=”List”

export myfile

echo “Displaying $myfile”

pr –t –n $myfile

printfile



 

printfile脚本程序清单:



echo “Printing $myfile”

lpr $myfile&



$dispfile

Displaying List

1 screen

2 modem

3 paper

Printing List

$

定制Bash

在本节中已经介绍了很多定制Bash的方法,但是迄今为止,这些方法都只是对当前Bash对话有用。只要用户退出登录,所做的一切改变都会丢失。所以应该在Bash的初始化文件中做永久性的修改。

用户可以将每次启动Bash所需要执行的命令放入初始化文件中,最常见的命令就是alias命令和变量定义两种。系统中的每个用户在其主目录中都有一个.bash_profile文件,Bash每次启动时都将读取该文件,其中包含的所有命令都将被执行。

下面便是默认.bash_profile文件的代码:

#.bash_profile

#Get the aliases and functions

if [-f ~/.bashrc ];then

.~/.bashrc

fi

#User specific environment and startup programs

PATH=$PATH:$HOME/bin

ENV=$HOME/.bashrc

USERNAME=””

Export USERNAME ENV PATH
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值