Linux命令(文件和文本篇)_第1页
Linux命令(文件和文本篇)_第2页
Linux命令(文件和文本篇)_第3页
Linux命令(文件和文本篇)_第4页
Linux命令(文件和文本篇)_第5页
已阅读5页,还剩255页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

[Linux命令]

[文件和文本篇]

目录

Shell基础及工具篇

1今天的主角是Shell

2用chsh来改变Shell

3export将环境变量昭告天下

4read,倾听是一种美德

5oxpr,一款多功能计算器

6tmux给你带来多窗口的享受

7用alias起个昵称吧

8history是历史的镜子

9xargs绝对的护花使者

10time,你最懂时间

11sleep,睡眠也有学问

文件和磁盘篇

1file命令探寻文件信息

2In连接你我他

3find命令上篇一一find初体验

4find命令下篇find引出的正则知识

5du最了解磁盘占用

6压缩系列之gzip

7压缩系列之二bzip2

8压缩系列之三zip

9dd造出最大的黑洞

文本处理篇

1echo命令上篇一一帮你发声,替你歌唱

2echo命令下篇一一让世界充满色彩

3搜索三兄弟grep、egrep和fgrep

4sed的流艺术之一初体验

5sed的流艺术之二花样命令

6sed的流艺术之三一露几手

7sed的流艺术之四一一插入和控制

8awk是三兄弟系列之入门

9awk是三兄弟系列之二一一多行操作

10awk是三兄弟系列之三--多文件操作

11awk是三兄弟系列之四外部调用

12awk是三兄弟系列之五一一实战

13cut是修剪小能手

14wc帮你计算字数

15split是拆分小能手

16paste用来拼接

17sort命令上篇sort帮你排序

18sort命令下篇关于k选项的大讨论

19Vi中的替换艺术

20加密工具全家桶

Shen基础及工具篇

在Shell及工具篇中,我们将为大家带来11篇文章,所有内容都是围绕着Shell展开

的,包括了:

•今天的主角是Shell

•用chsh来改变Shell

•export将环境变量昭告天下

♦read,倾听是一种美德

•expr,一款多功能计算器

•tmux给你带来多窗口的享受

•用alias起个昵称吧

•history是历史的镜子

•xargs绝对的护花使者

•time,你最懂时间

•sleep,睡眠也有学问

在这里,你不仅可以了解到Shell发展历史中的趣闻、感受到tmux的便捷,还能掌

握配置history的各种方法

让我们现在就开始Shell学习之旅吧!

1今天的主角是Shell

老婆问我什么是Shell

面对做会计行业的老婆,我没有信心回答好这个问题。

但是对于阅读本书的读者们来说,相信大家都有计算机知识背景,所以,我还是很

有信心能够解释清楚的。

首先,我们今天所说的Shell,既不是海滩上美丽的贝壳儿,也不是荷兰那家鼎鼎大

名的壳牌公司,而是用在UNIX/Linux操作系统中的一个叫作Shell的工具。

其次,众所周知,UNIX/Linux操作系统的心脏是”内核〃,内核主要负责控制硬

件、管理内存和调度任务,而Shell则是用户与操作系统之间的一座桥梁,用户可以

利用Shell实现对UNIX/Linux操作系统及其内核的控制和操作。

最后,Shell已经发展成为一种解释型编程语言,它不仅包含了大量的命令以实现与

操作系统的对话,还可以实现变量定义、条件判断、循环控制、函数调用等功能,

我们完全可以利用Shell实现很多复杂的业务逻辑,

如果只用一张示意图来说明什么是Shell的话,那么下面的这张图再合适不过了。

图1什么是Shell

一睹Shell的芳容

当我们打开一台安装有UNIX/Linu乂操作系统的电脑,输入用户名、密码登录成功

后,系统便会启动一个Shell,它是一个交互式的界面,会等待我们输入指令,就像

这样:

[roc@roclinux

当我们输入了一条命令之后,Shen会经过一系列的处理环节,然后执行,并为我们

返回执行结果,就像下面这样;

[roc@roclinux~]$uname-aLinuxroclinux2.6.32-220.4.1.el6.x8664

#1SMPTueJan2402:13:44GMT2012x86=64x86_64x86_64GNU/Linux

大家可以看到,我们输入的命令是"uname-a",这是一个显示操作系统基本信息

的Shell命令,像这样的命令,在Shell中有上千个,比如Is.alias,cat、

chgrpxawk、ulimit、rm,等等。

下面来一起看一下Is命令的运行效果,如图2所示。

•••2roc@roclinux;~/progfam(ssh)

[roc0rcclinuxprogram]$Is

auth.rbgomysqlphp-vim

bzip2-l.046gol.1.2mysql-5.6.14php-vim74

■•

composer»pharhadoop-1.2.1mysql-5.6.20php-5.5.5.pdo.gdyii

curl-7.34.0iproute2-4.4.0nginxredisyii-l.1.13

gangliajqnginx-1.4.3redis-2.6.16

ganglia-3.6.1json-cnginx-1.4.4splan

gitlibeventPhpthrift

git-libevent-2.0.21php-5.5.22thrift-0.9.1

[roc@roclinuxprogram]$.

图2Is命令的运行效果

对于Shell高手来说,交互式Shell不能完全满足他们的日常需要,他们更善于把工

作和任务通过自动化方式来完成,所以,Shell脚本应运而生。

当把多个Shell命令按照一定的逻辑写到一个文件中时,这个文件就可以被叫

作"Shell脚本文件"。而执行这样的脚本,就可以实现一部分工作的自动化了。

世界上第一款Shell

开门见山,世界上第一款Shell,叫作ThompsonShell,于1971年诞生,1975年

开始广泛传播。那时很多阅读这本书的同学或许还没有出生吧。

至于为什么叫作ThompsonShell,故事要从1965年说起。

那一年,贝尔实验室参与到了一个意义重大的项目中,那就是和美国通用电气、麻

省理工学院共同开发一个多用户、多进程的操作系统,产品代号为"Multics"。

一年后,故事的主人公,年仅23岁的有志青年Thompson加入贝尔实验室,参与到了

Multics项目的开发中来。

不幸的是,由于进度缓慢,Multics项目在1969年搁浅了。而Thompson却在这个项

目中积累了大量的操作系统设计经验,并在次年开始了一款全新操作系统的开发工

作,这就是后来赫赫有名的UNIX。1970年,也因此被称为UNIX元年!

很快,就在1971年;UNIX在实验室范围内发布了它的VI版本,而ThompsonShell

也随之诞生。1975年,UNIX的第六个版本面向公众发布,ThompsonShell也随之

得到了广泛地传播。

所以ThompsonShell也被叫作V6Shell。

那些年,我们一起追的Shell

2011年,九把刀导演的《那些年,我们一起追的女孩》上映,人们都在回忆自己曾

经追过的女孩。而作为Linux爱好者,有没有你曾经追过的Shell呢?

在Linux的历史长河中,曾经出现过很多种类的Shell,它们之间有的是传承关系,

有的是竞争关系,有的已经不为人所知,有的则家喻户晓。

大浪淘沙过后,最终流传下来的Shell,才是值得我们了解和学习的Shell,如表1

所示。

表1值得了解和学习的Shell

名称全称诞生于流行于

shBourneShell1977UNIX

(t)cshCShell1978UNIX

kshKornShell1983UNIX

bashBourneAgainShell1989Linux

zshZhongShaoShell(非官方说法)1990Linux

dashDebianAlmquistShell2002Linux

其实还有一些偏小众的Shell,大家有兴趣也可以去了解和关注一下,如pdksh.

scsh、psh、mksh,等等。

zsh是中国人开发的么

我猜一定会有人问,zsh的全称是ZhongShaoShell,难道zsh是中国人开发的

么?

非也,非也。zsh的作者是美国普林斯敦大学的一位学生,他的名字叫作Paul

Falstado当时有一位名叫ZhongSha。的助教,他登录LinuxShell时使用的ID是

zsh,Paul非常喜欢这个名字,恰好z的美式英语的发音和csh的c又非常像,于是就

选择了zsh作为自己编写的Shell的名字了。

是不是很有趣呢,我们再来讲一个有关csh的故事。

回到遥远的1978年,那时的Billjoy(BSD操作系统作者、TCP/IP设计者、vi作

者、NFS作者、SUN公司创立者之一)年仅24岁,正在加州大学伯克利分校攻读硕士

学位。那一年,他为BSD开发了一款Shell,起名叫作CShell,简称csho之所以

叫CShell,是因为它的语法和C语言非常相似。

而在1978年到1983年间,又有多位计算机专家在csh的基础上增加了丰富的功能,

包括拼写校验、历史记录、作业控制、命令行编辑器等。在为这个增强版csh取名

时,专家们借鉴了历史上一种具有〃命令补全"功能的操作系统TEYEX的灵感,最终

将它取名为tcsh,即TENEXcsho

让Shell飞入寻常百姓家

唐代诗人刘禹锡,在《乌衣巷》中的一句"旧时王谢堂前燕,飞入寻常百姓家",

流传至今。

而我们希望曾经闻名遐迩的各种Shell,也能"飞入"我们的电脑,让我们能更近距

离地感受它们的设计思想和功能e

以CentOS发行版为例,如果想查看当前系统都安装了哪些Shell,可以这样:

[root@roclinuxcat/etc/shells/bin/sh/bin/bash/sbin/nologin

可以看到,/etc/shells文件中记录了"当前系统中安装了哪些种类的Shen〃:

•/bin/sh:这是BourneShell0

•/bin/bash:这是BourneAgainShell。

/bin/nologin:这并不是一个Shell,而是指"无法登录

那么系统当前使用的到底是什么Shell呢,我们可以这样来查看:

[root@rodinuxecho$SHELL/bin/bash

可见,我们当前所使用的是BourneAgainShell。

如果想尝试一下zsh,应该怎么安装呢?非常简单:

[root@roclinuxyuminstallzsh

就这样一条语句,就可以让zsh〃飞”入你家6

安装完成后,是不是已经迫不及待地想体验一下zsh7!这也不难:

#首先定位到zsh的绝对路径[root@roclinuxwhichzsh/bin/zsh#使用・

s选项更改登录Shell的类型[root@roclinux~]$chsh-s/bin/zsh

Changingshellforroot.Shellchanged*

只需上面两步,我们就已经把root账户的登录Shell更改为zsh7,接下来,只要退

出当前shell,再以root账户重新登录进来,就可以享受zsh啦!

如果想让其他的Shell也“飞“进你家,如法炮制就好。

可以评价下这些Shell么

我们不会把每种Shell的优缺点都列在这里,因为曾经追的很多Shell,现如今已不

是主流,有被新Shell替代的,也有因功能欠缺被淘汰的。所以,为了节省时间,这

里只简单聊聊bash和zsh这两种Shell,原因是,前者主流,后者强大。

bash当属使用最广泛的Shell了,它融合了csh和ksh的长处,规避了两者的短处,

是目前Shell中的首选。许多Linux系统、MACOS系统都将bash作为了系统的默认

Shell,所以大家也会看到,非常多的书籍、示例、项目都是面向bash的,本书也

不例外,毕竟,我们应该将有限的时间用在收益最大的事情上,对不对。

zsh,被有些人称为〃终极Shell"。这并不算夸张,zsh真的算是Shell中的集大成

者,它融合了tcshxksh和bash的优秀之处,而且还完全兼容bash,对于用惯了

bash的同学来说,几乎可以无缝迁移。而zsh在历史记录提示、命令补全、别名、

语法高亮等方面都有着超出预期的用户体验。

好了,本书的第一篇文章就到这里了。本文中用到的chsh命令,我们会在下一篇中

进行重点讲解,来,一起进入下一篇!

2用chsh来改变Shell

我想知道我机器安装了哪些Shell

chsh命令本身并不复杂,它的功能比较单一,就是负责展示和修改我们系统的登录

Shelly

想修改登录Shell,首先要知道我们的系统安装了哪些Shell.这里有两种方法可以

查看.

方法一:

[roc@roclinuxchsh-1/bin/sh/bin/bash/sbin/nologin/bin/zsh

方法

[roc@roclinux~]$cat/etc/shells/bin/sh/bin/bash/sbin/nologin

/bin/zsh

其实chsh-1命令本质上也是去查看/etc/shells文件。

查看当前正在使用的Shell

只使用一个环境变量,就可以查看到当前正在使用的Shell啦:

[roc@roclinux~]$echo$SHELL/bin/bash

注意:SHELL一定要大写。可以看到,我们目前使用的Shell是bash。

听说zsh不错,于是我们就通过在命令行执行zsh命令切换到了zsh环境。可是,为

什么查看当前Shell类型仍然是/bin/bash呢?

[roc@roclinux~]$zsh[roc@roclinux]~%echo$SHELL/bin/bash

[roc@roclinux]~%

请注意,我们虽然执行了zsh,但是所谓〃当前的Shell"是一个大环境的概念,是

针对一个已登录的用户而言的。而我们执行zsh只是启动了一个zsh的解释器程序而

已,并没有改变大环境。如果想改变"当前的Shell",那么还是要求助于chsh才

可以。

将Shell环境真正切换到zsh

[roc@roclinux~]$chsh-s/bin/zshChangingshellforroc.

Password:Shellchanged.

使用Chsh命令的-s选项就可以修改登录的Shell了。

如果我们这时候满怀欣喜地执行echo$SHELL,就会发现然输出的仍是/bin/bash。

这是因为chsh改变的是我们登录Shell的配置,我们必须退出再重新登录Shell,才

可以完全投入到zsh的怀抱。

真是一波三折,退出并重新登录后,终于看到了我们想要的/bin/zsh了:

[roc@roclinux]~%echo$SHELL/bin/zsh

chsh-s到底修改了哪里

到了揭开迷底的时刻啦!

chsh-s其实修改的就是/etc/passwd文件中和我们所登录的用户名相对应的那一

行。现在我们来查看一下:

[roc@roclinux]~%cat/etc/passwd|grepAroc

roc:x:1001:1001;;/home/roc:/bin/zsh

可以发现,输出内容的最后部分已经变成了/bin/zsh了。重启系统的时候,Linux

就会读取这一命令来启动新的Shell。

好了,我们要恢复正常的工作环境,把Shen修改回我们熟悉的/bin/bash了:

[roc@roclinux]~%chsh-s/bin/bashChangingShellforroc.

Password:Shellchanged.

3export将环境变量昭告天下

export可以展示Shell环境变量

我们直接进入正题,先来看看执行export会输出什么内容:

[roc@roclinux~]$exportdeclare-xCVS_RSH="ssh"declare-x

GEM_H0ME="/usr/local/rvm/gems/ruby-2.2.3"declare-x

GEM_PATH="/usr/local/rvm/gems/ruby-2.2.3:/usr/local/rvm/gems/ruby-

2.2.3@global"declare-xG0R00T="/home/roc/program/go"declare-x

G_BROKEN_FILENAMES="1"declare-xHISTCONTROL="ignoredups"declare

-xHISTSIZE="1000"declare-xHOME=*7home/roc"declare-x

HOSTNAME="roclinux"declare-xIRBRC="/usr/local/rvm/rubies/ruby-

2.2.3/.irbrc"declare-xJAVA_HOME='7usr/lib/jvm/jre-1.7.0-

openjdk.x86_64"declare-xLANG="zh_CN.gb2312"declare-x

LC_ALL="zh_CN,gb2312"declare-xLESSOPEN="|/usr/bin/lesspipe.sh

%s"declare-xLOGNAME="roc"declare-x

LS_COLORS="rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;ll:so

38;5;13:do=38;5;5:bd=48;5;232;38;5;ll:cd=48;5;232;38;5;3:or=48;5;232

38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;ll;38;5;16

ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;2

;38;5;15:ex=38;5;34:*,tar=38;5;9:4e.tgz=38;5;9:*.arj=38;5;9:*.taz=38;

;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.zip=38;5;9

*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lz=38;5;9:*.xz=38;5;

:*.bz2=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.bz=38;5;9:*.tz=38;5;9:*.d

b=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.rar=38;5;9:*.ace=38;5;9:*.zoo=3

;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.jpg=38;5;13:*.jpeg=38;5

13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;

;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=3

;5;13:*.png=38;5;13:*.5Vg=38;5;13:*.5Vgz=38;5;13:*.mng=38;5;13:*.pcx

38:5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.in2v=38;5;13:*.m

v=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4V=38;5;13:*.mp4v=38;5;13:*

vob=38;5;13:**qt=38;5jl3:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*

rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:

.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5j13:*

yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13;

.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45

*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;

5:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;

5:*.spx=38;5;45:*.xspf=38;5;45:"declare-x

MAIL="/var/spool/mai1/roc"declare-x

MY_RUBY_HOME="/usr/local/rvm/rubies/ruby-2.2.3"declare-x

OLDPWD=,7home/roc/test/20160403"declare-xPATH="/usr/1ib/jvm/jre-

1.7.0-openjdk.x86_64/bin:/home/roc/program/yii

/framework/:/home/roc/program/php/bin:/home/roc/bin:/home/roc/progra

/thrift/bin:/home/roc/program/go/bin:/home/roc/program/vim/bin:/home

roc/program/git/bin:/home/roc/bin:/usr/lib/jvm/jre-1.7.0-

openjdk.x86_

64/bin:/home/roc/program/yii/framework/:/home/roc/program/php/bin:/h

me/roc/bin:/home/roc/program/thri-Ft/bin:/home/roc/program/go/bin:/ho

e/roc/program/vim/bin:/home/roc/program/git/bin:/usr/local/rvm/gems/

uby-2.2・3/bim/usr/local/rvm/gems/ruby-

2.2.3@global/bin:/usr/local/rvm/rubies/ruby-

2.2.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:

/usr/sbin:/sbin:/www/wdlinux/mysql/bin:/usr/local/rvm/bin:/home/roc/

in:/www/iA/dlinux/mysql/bin:/home/roc/bin"declare-xPWD="/home/roc"

declare-xRUBY_VERSION="ruby-2.2.3"declare-xSHELL="/bin/bash”

declare-xSHLVL="2"declare-xSSH_CLIENT="3452932

22000"declare-xSSH_CONNECTION="9211887

0622000"declare-xSSH_TTY=,7dev/pts/lndeclare-x

TERM="screen-256color"declare-xTMUX=

1001/default,35631,0"declare-xTMUX_PANE="%25"declare-x

USER=Hroc,*declare-x_system_arch=**x86_64'1declare-x

_system_name="CentOS"declare-x_system_type="Linux"declare-x

_system_version="6"declare-xrvm_alias_expandeddeclare-x

rvm_bin_flagdeclare-xrvm_bin_path="/usr/local/rvm/bin"declare-

xrvm_delete_flagdeclare-xrvm_docs_typedeclare-xrvm_file_name

declare-xrvm_gemstone_package_filedeclare-xrvm_gemstone_url

declare-xrvm_hookdeclare-xrvm_nicenessdeclare-x

rvm_nightly_flagdeclare-xrvm__only_path_flagdeclare-x

rvm_path="/usr/local/rvmndeclare-xrvm_prefix=,,/usr/locar,

declare-xrvm_proxydeclare-xrvm_quiet_flagdeclare-x

rvm_ruby_aliasdeclare-xrvm_ruby_bitsdeclare-x

rvm_ruby_configuredeclare-xrvm_ruby_filedeclare-x

rvm_ruby_global_gems_pathdeclare-xrvm_ruby_makedeclare-x

rvm_ruby_make_installdeclare-xrvm_ruby_modedeclare-x

rvm_ruby_stringdeclare-xrvm_ruby_urldeclare-xrvm_script_name

declare-xrvm_sdkdeclare-xrvm_silent_flagdeclare-x

rvm_sticky_flagdeclare-xrvm_system_flagdeclare-xrvm_use_flag

declare-xrvm_user_flagdeclare-xrvm_version="l.26.11(master)"

declare-xrvm_wrapper_name

export输出的内容就是bash的所有环境变量了,满满的两页看来还真是不少呀。

env/set/export/declare的区别

在Linux系统中,除了export之外,envxset和declare这三个命令也可以显示

Shell中的变量。那这四个命令有什么区别呢?

这个问题,我们需要从Shell变量说起。Shell的变量,可以分为“环境变

量〃和"自定义变量"两种类型,两者的区别在于作用范围不同。环境变量可以在

其进程的子进程中继续有效,而自定义变量的势力范围则无法延伸到其进程的子进

程中。

好了,知道了环境变量和自定义变量的区别,我们正式开始介绍

export/env/set/declare的区别:

•env:显示当前用户的环境变量,但不会显示其自定义变量。

•export:功能同env一样,也是显示当前用户的环境变量,只不过该命令的输出

是按变量名进行排序的。

•declare;显示当前Shell中定义的所有变量,包括用户的环境变量和自定义变

量,该命令的输出按变量名进行排序。

•set:功能同declare一样,显示当前Shell中定义的所有变量,包括用户的环境

变量和自定义变量。

根据上面的说明,我们可以得出下面的结论:

•env和export显示的是环境变量。

•set和declare显示的是环境变量和自定义变量。

我们以set和declare为例,来看一下是否真的是这样:

[roc^roclinux~]$set>set.txt[roc@roclinuxdeclare>

declare.txt[roc@roclinuxdiffset.txtdeclare.txt54c54<

_=clear—>_=set

看到了吧,set和declare的输出几乎是一样的。

唯一的区别就在于这个〃下划线变量"。下划线变量(_)表示用户上一次输入的命

令的最后一个参数。上面两条命令之所以出现不同,是因为在执行set前执行了

clear命令,而在执行declare之前,执行了set命令。

设置ShQll环境变量

$PATH环境变量是Linux系统中最常用的变量之一,我们先来看一下这个变量的内

容:

[root@roclinux-]#echo$PATH

/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/b

相信细心的同学已经观察到了,$PATH变量的值是由多个路径所组成的,并且用冒号

进行了分隔。那么,问题来了,这些路径的作用是什么呢?

当用户在Linux系统中直接输入一个命令(如date命令),而没有指定其绝对路径

时,Linux就会求助于$PATH啦,Linux会依次进入到$PATH变量所指定的各个路径

中,去寻找是否存在此命令(date命令),如果找到了,就执行该命令;如果没有

找到,就直接退出,并提示用户未找到该命令。

在运维工作中,用好$PATH变量是可以大大提升工作效率的。假

如/home/roc/operation_tools文件夹下存放着我们自制的各种运维小工具,每次

使用这些小工具时又不想总指定其绝对路径,那么,我们应该怎么办呢?没错,我

们应该把这个路径追加到$PATH变量中去,具体的做法是这样:

exportPATH=$PATH:/home/roc/operation_tools

上述命令执行成功后,我们的运维小工具就可以直接被Linux系统找到了。从此以

后z当我们想使用这些运维小工具时,就再也不用指定绝对路径啦。

让你真正体会export的威力

不知道你是否注意到上面例子中的一个细节,那就是我们在设置$PATH环境变量时,

使用了export命令。如果没有使用export,会有什么问题吗?

这个问题问得很好,这正好引出export的作用,那就是,使用export设置的变量就

成为了环境变量,而没有使用export设置的则是自定义变

下面我们通过一个示例来看一下:

#我们在当前Shell进程中指定了varl变量[roc@roclinuxvarl="hello"

[roc@roclinux~]$echo$varlhello#我们在当前Shell进程中又指定了var2

变量[roc@roclinux~]$var2="worldH[roc@roclinux~]$echo$var2

world#我们通过export发布varl[roc@roclinux~]$exportvarl#我们进

入到一个bash子进程中[roc@roclinux~]$bash变量仍然有效,而var2

变量已经无效了[roc@roclinux~]$echo$varl#输出变量的值hello

[roc@roclinux~]$echo$var2#什么也没有输出

通过上面的示例,我们可以清楚地看到;环境变量可以在其进程的子进程中继续有

效,而自定义变量则无效。

误操作惹的祸

"哎呀,不好了,我的Linux系统出问题了,我竟然连st命令都没办法运行了,执

行时总是提示我找不到命令,这是怎么回事?我只是按照上面的示例执行了一下命

令,就成这个样子了,我该怎么办啊?"

”同学,让我看看你到底执行的是什么命令?"

"我执行的命令,很简单,就是这个:"

$exportPATH=/home/to/operation_tools

〃额,问题找到了,你的命令输错啦,来看正确的用法吧。

$exportPATH=$PATH:/home/to/operation_tools

再对比一下你的命令,你的命令中缺少了$PATH,这样会清空原来$PATH的内容,

$PATH中没有了系统指定的路径Linux就无法找到要执行的命令。这是一个多么可怕

的误操作啊!

大家一定要记住这个教训呀,在设置PATH环境变量时要格外小心哦。

4read,倾听是一种美德

人生第一次编程

不知道你是否还记得你的第一次计算机编程。

我对"第一次"记忆犹新,那是一个很神奇的时刻。当我把有生以来编写的第一个C

程序交给计算机执行时,黑色的屏幕上显示出了一行字"pleaseinputyour

name:°

我怀着无比激动的心情写下我的名字,然后按下回车。美妙的时刻就此凝固

了,计算机毫无差错地显示出:

welcome!!!roc.

如果现在让你用Shell来实现同样效果的程序,不知道你是不是能很快就写出来呢?

本文就来帮你实现这个程序,在实现该程序之前,我们还是先来学习一下Linux系统

中最擅长倾听的命令——read吧。

倾听键盘的声音

read命令用来倾听标准输入或文件输入,并把信息存放到变量中。

从read命令的定义可以看出,倾听键盘是read的主要职责之一。

现在,我们用Shell来模拟一下上面的(:程序吧:

#!/bin/bashecho-n"pleaseinputyourname:"readnameecho

"welcome!!!$name"exit0

就这么简单,使用read命令来倾听用户的输入,并把用户的输入内容自动保存到指

定的name变量中,最后使用echo实现输入内容的显示。

上面的Shell脚本是不是已经是最精简的了?当然不是,还可以继续精简,我们可以

直接使用read自带的显示提示语功能,省略程序中的echo语句:

#!/bin/bashread-p"pleaseinputyourname:"nameecho"welcome

!!!$name"exit0

上面脚本中的read的叩选项就是用来显示提示语的。

在这个例子中,我们只是让read来接收name变量的值,那么read可以同时接收两个

甚至更多的变量吗?答案是可以的。

#!/bin/bashread-p"pleaseinputyournameandplace:'*nameplace

echo"welcome$nameto$place"exit0

看到了吗?read后面可以指定两个变量name和place,当用户输入完成时,read会

以空格来分割用户的输入内容,并把输入的内容分别存放到后面的变量中。

按照这个规律,read完全可以指定3个、4个……N个变量。需要注意的是,当用户的

实际输入和程序期望输入的变量个数不等时,又会出现什么情况呢?

这是一个好问题,比如上面的脚本期望用户输入name和place两个变量的值,而我

们却故意输入一个数据或三个数据,这时来看看脚本的执行情况:

示例一:只输入一个数据

[roc@roclinux./test.shpleaseinputyournameandplace:roc

welcomerocto

示例二:输入多个数据

[roc@roclinux~]$./test.shpleaseinputyournameandplace:roc

beijingshanghaitianjinwelcomeroctobeijingshanghaitianjin

通过上面脚本的执行,我们可以得出以下的结论:

1.如果输入的数据数量少于变量的个数,那么多余的变量不会获取到数据,即变量

值为空。

2,如果输入的数据数量多于变量的个数,那么超出的数据将都赋值给最后一个变

J=L

里。

还有一个非常特殊的情况,就是在编写脚本时,如果read命令后面没有写任何变

量,脚本执行时,我们输入数据,那输入的数据会存放到哪里呢?

对于这种极端情况,Shell的设计者早就预料到了:用户的数据会存放到一个叫作

$REPLY的环境变量中去。

#!/bin/bash##read-p"pleaseinputyournameandplace:"echo

"welcome$REPLY"exit0[roc@roclinux~]$bashtest.shpleaseinput

yournameandplace:rocbeijingwelcomerocbeijing

倾听也可以有时间限制

read,非常乐于倾听用户的声音,但有的时候,用户长时间不输入,那read也可以

有自己的后手。

redd命令提供了选项,可以用来设置一个倾听的时限。如果超过所设置的时限的

话,那么read的耐心也就到此为止喽.

#!/bin/bashifread-t5-p"pleaseinputyournamewithin5s:"

namethenecho"welcome!!!$name"elseecho"sorry,tooslow"fi

exit0

上面的脚本就使用了选项,用来指定等待输入的时长(秒)。

上述脚本表示read会等待用户的输入,但丑话说在前,如果5秒内用户没有响应,那

么read就会自动结束,并显示"sorry,tooslow"来抱怨一下用户。可见,read

命令也可以有自己的态度的。

密码输入场景

还有一种使用场景非常特殊,就是密码输入,我们都不希望密码明文显示在屏幕

上,万一被别人看到了,可就不妙了。对于这种场景,我们希望实现隐藏输入的效

果,read命令使用.s选项即可实现这样的效果;

#!/bin/bashread-s-p"pleaseinputyourcode:"passwordecho

"hehe,yourpasswordis$password"

上面的程序使用了-S选项,它实现的效果是用户在输入的时候,屏幕上不显示任何

信息。

这样,是不是再也不用担心密码被别人看到了?

内容来自文件

前面我们说过,read命令不仅能监听键盘输入,还能读取文件内容,上面的示例都

在说键盘,下面就来说文件。

首先,我们准备一个素材文件,其内容如下:

[roc@roclinux~]$cat-ntest.txt119248219247319246

下面,我们为大家展示read命令的三种读取文件的方法。

第一种方法:使用-u选项

#!/bin/bash#assignthefiledescriptortofileforinputfd#3

isInputfileexec3<test.txt#readthefileusingfd#3count=0

whileread-u3vandoletcount=$count+lecho"Line$count:$var"

doneecho"finished"echo"Linenois$count"#Closefd#3exec

3<&-

上面的脚本通过°exec3<test,txtw生成了编号为3的文件描述符,接着通

过Mread-u3varw来读取文件内容。最后通过"exec3<&-"关闭了3号文件描

述符。

我们来看下脚本的执行效果

#执行效果[roc@roclinux./test.shLine1:19248Line2:19247

Line3:19246finishedLinenois3

第二种方法:使用管道

#!/bin/bashcount=lcattest.txt|whilereadlinedoecho"Line

$count:$line"letcount=$count+ldoneecho"finished"echo"Lineno

is$count"exit0

请注意上面的用法"cattest.txt|whilereadline",通过这样的方式来遍历

test.txt文件的内容,并按行赋值给变量line。

#执行效果[roc@roclinux-]$./test.shLine1:19248Line2:19247

Line3:19246finishedLinenois1

咦,有个问题°脚本最后输出的是Linenois1,怎么行数是1呢,明明是3才对

啊?

上面这个问题,是由于管道导致的。我们知道,管道的两边一般需要新建进程,当

执行完while语句后,新进程也就结束了6而脚本中count是新进程中的自定义变

量,进程结束后该变量也就消失了(自定义变量的生命周期结束)o当脚本执行

echo时,显示的count变量是脚本中第一行定义的变量的值,而不是while语句中的

那个count变量了,因而输出的结果当然就是1了。

第三种方法:使用重定向

由于第二种方法中的count变量计数有误,所以我们继续为大家介绍第三种方法,这

种方法可以有效规避因为新建进程而导致的变量值无法保留的问题。

#!/bin/bashcount=0whilereadlinedoletcount=$count+lecho

"Line$count:$line"done<test.txtecho"finished"echo"Lineno

is$count"exit0

运行脚本,看看执行结果是否符合预期;

[roc@roclinux~]$bashtest.shLine1:19248Line2:19247Line

3:19246finishedLinenois3

分析上面的第二种方法和第三种方法可以发现,它们最核心的区别是"管道技

术"变成了"重定向技术",从而成功规避了进程中新生成自定义变量的问题e

神奇的换行符

我们接着上面重定向的例子来说,我们把test.txt文件的内容稍微变动一下。

[roc@roclinuxcat-ntest.txt119248\219247\319246

可以看到,我们在前两行的后面分别加上了一个反斜线(\),这个符号表示续行

符,它实现的效果是〃肉眼看上去是换行了,但是Linux认为并没有换行"。

如果我们把这个文件作为上面例子的输入,那么会输出什么呢?我们来看一下实际

效果:

[roc@roclinux~]$,/test.shLine1:192481924719246finishedLine

nois1

是不是和你想的一样?这就是续行符(\)的作用,read命令在读取数据时,当读取

到续行符(\)时,它不认为这是一行的结束,而是会继续读取下一行,直到遇到真

正的换行符(\n)为止。

这样一解释,大家就应该知道为什么脚本执行结果里只有Line1了吧。

其实在read读取到的数据中,所有的转义符表示的特殊含义都是起作用的,如果你

不想让它们起作用的话,请使用选项吧。

#!/bin/bash#assignthefiledescriptortofileforinputfd#3

isI

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论