设为首页 收藏本站
查看: 856|回复: 0

《Shell脚本学习指南》第二章学习笔记

[复制链接]

尚未签到

发表于 2015-10-26 10:09:49 | 显示全部楼层 |阅读模式

2.1 脚本编程语言与编译型语言的差异

编译型语言从源代码转换成目标代码,便能直接通过计算机执行。好处是高效,但运作于底层。例如,在C++里,很难进行“将一个目录里所有的文件复制到另一个目录中”之类的简单操作。
脚本编程语言通常是解释型(Interpreted)的。由解释器读入程序代码,并将其转换成内部的形式,再执行。解释器本身是一般的编译型程序。

2.2 为什么要使用Shell脚本
脚本执行效率通常不如编译型语言,但它已经足够快了,足以忽略它性能上的问题。花一个小时写成的简单脚本,同样的功能用C或C++来编写实现,可能需要两天。脚本编程语言的例子有awk、Perl、Python、Ruby与Shell。
因为Shell是各Unix系统之间通用的功能,并且经过了POSIX的标准化。只要用心写一次,即可应用到很多系统中。

2.3 一个简单的脚本
自动化统计当前有多少用户登录系统。其中用到了who命令,wc -l统计行数以及管道。
$ cat > nusers          建立文件,使用cat复制终端的输入who | wc -l^D                         Ctrl-D表示end-of-file$ chmod +x nusers    让文件拥有执行的权限$ ./nusers                执行测试     6
这展现了小型Shell脚本的典型开发周期:1. 直接在命令行上测试,找到能够完成工作的适当语法。2. 将它们放进一个独立的脚本里,并为该脚本设置执行的权限。3. 之后就能直接使用该脚本了。

2.4 自给自足的脚本:位于第一行的#!
当一个文件中开头的两个字符是#!时,内核会扫描该行其余的部分,看是否存在可用来执行程序的解释器的完整路径。此外还会扫描是否有一个选项要传给解释器。
#! /bin/csh -f
下面是几个初级的陷阱:1. 各系统对#!这一行的长度限制从64到1024字符都有,所以尽量不要超过64个字符。2. 别在选项之后放置任何空白,因为空白也会跟着选项一起传递给被引用的程序。

2.5 Shell的基本元素
2.5.1 命令与参数
命令名称是命令行的第一个项目,后面跟着选项。选项可有可无,还可以合并,如ls -lt比ls -l -t更方便。长选项在标准工具GNU版本,以及X Window System中使用的越来越普遍,如patch --verbose --backup。分号;可用来分隔同一行里的多条命令,Shell会依次执行这些命令。用&符号,则Shell将在后台执行其前面的命令,Shell不用等待该命令完成就可以继续执行下一个命令。
Shell识别三种基本命令:内建命令、Shell函数以及外部命令
1.内建命令就是由Shell本身所执行的命令。有些命令是由于必要性(需要改变父Shell进程的属性)才内建的。如cd用来改变目录,read将用户输入传给Shell变量。另外一些是为了效率,如test命令,还有I/O命令echo与printf。
2.Shell函数用Shell语言写成的,可以像命令那样引用的代码。
3.外部命令就是Shell子进程所执行的命令,基本过程如下:a.新建一个父Shell进程的子进程。(fork)b.在新进程里搜索PATH变量列出的目录,找到特定命令。当命令名称含有斜杠/时,略过路径查找步骤。c.在新进程里,用找到的程序取代执行中的Shell程序并执行。(exec)d.程序完成后,父Shell进行继续从终端读取下一条命令,或执行脚本里的下一条命令。
2.5.2 变量
Shell变量名称的开头是一个字符或下划线,后面可以接着任意长度的字母、数字或下划线。变量名称和变量保存的字符串的长度都没有限制。在变量名称前加$字符取出Shell变量的值。当给变量赋予的值包含空格时,需要加上引号。
$ myvar=this_is_a_long_string$ echo $myvar
$ first=issac middle=bashevis last=singer     单行可进行多次赋值$ fullname="issac bashevis singer"$ fullname="$first $middle $last"$ oldname=$fullname
2.5.3 简单的echo输出
$ echo Now is the time for all good menNow is the time for all good men
echo有版本上的差异,但只要是使用最简单的形式,其echo的可移植性不会有问题。
BSD版本的echo,-n参数会省略结尾的换行符号。$ echo -n "Enter your name: "Enter your name: _
System V的echo会处理转义字符,\c表示忽略换行符号。$ echo "Enter your name: \c"
2.5.4 华丽的printf输出
printf命令模仿C程序库里的printf()程序,几乎复制了该函数的所有功能。$ printf "Hello, world\n"$ printf "The first program always prints '%s, %s'!\n" Hello world最大不同在于:printf不像echo那样自动提供一个换行符,必须显式指定\n。
2.5.5 基本的I/O重定向
标准输入/输出可能是软件设计原则里最重要的概念了。程序不必知道也不用关心它的输入与输出背后是什么设备:磁盘上的文件、终端、磁带机、网络连接或是另一个执行中的程序!当程序启动时,可以预期的是,标准输入输出都已打开,且已准备好供其使用。
许多Unix程序都遵循这一设计原则。默认情况下,它们会读取标准输入、写入标准输出,并将错误信息传递到标准错误输出。这类程序常叫做过滤器(filter)。默认的标准输入、标准输出以及标准错误输出都是终端。
$ cat                  未指定任何参数,读取标准输入,写入标准输出now is the time     由用户输入     now is the time     由cat返回for all good menfor all good men^D
在你登录时,Unix便将默认的标准输入、输出及错误输出安排成你的终端。
重定向与管道
以<改变标准输入:tr -d '\r' < dos-file.txt (命令tr -d '\r'将删除回车)以>改变标准输出,覆盖目的文件:tr -d '\r' < dos-file.txt > UNIX-file.txt以>>附加到文件,附加到文件结尾:for f in dos-file*.txtdo     tr -d '\r' >> big-UNIX-file.txtdone
以|建立管道:tr -d '\r' < dos-file.txt | sort > UNIX-file.txt将program1的标准输出修改为program2的标准输入。虽然<与>可将输入与输出连接到文件,不过管道的执行速度比使用临时文件的程序快上十倍。
构造管道时,应该试着让每个阶段的数据量变少。换句话说,如果你有两个要完成的步骤与先后次序无关,你可以把让数据量变少的那一步放在管道的前端,这样可以提升脚本的性能。例如,使用sort排序之前,先以grep找出相关的行,这样可以让sort少做些事。
特殊文件:/dev/null与/dev/tty
/dev/null就是大家所熟知的位桶(bit bucket),写到此文件的数据都会被系统丢掉。读取它则会立即返回文件结束符号(end-of-file)。
当程序打开/dev/tty时,Unix会自动将它重定向到一个终端,这在程序必须读取人工输入时特别有用。以下stty命令用来控制终端的各种设置。$ printf &quot;Enter new password: &quot;     提示输入$ stty -echo                              关闭自动打印输入字符的功能$ read pass < /dev/tty               读取密码$ printf &quot;\nEnter again: &quot;              提示再输入一次$ read pass2 < /dev/tty              再读取一次以确认$ stty echo                               恢复自动打印输入字符的功能$ echo$ echo pass is $pass, pass2 is $pass2
2.5.6 基本命令查找
如果要编写自己的脚本,最好准备自己的bin目录来存放它们,并且让Shell能自动找到它们。只要建立自己的bin目录,并将它加入$PATH中的列表即可。$ PATH=$PATH:$HOME/bin
要让修改永久生效,在.profile文件中把你的bin目录加入$PATH,每次登录时Shell都会读取.profile文件。
空项目或点号表示当前目录,如PATH=:/bin:/user/bin或PATH=/bin::/user/bin

2.6 访问Shell脚本的参数
Shell脚本的命令行参数,同时也是函数的参数。各参数都由整数来命名,超过9就应该用大括号。echo first arg is $1echo tenth arg is {$10}
查找某用户现在是否登录。$ cat > finduser#! /bin/sh# finduser -- find if user in argument one is login nowwho | grep $1^D$ chmod &#43;x finduser$ ./finduser betsy

2.7 简单的执行跟踪
打开执行跟踪功能会使得Shell显示每个被执行到的命令,并在前面加上“&#43;”和一个空&#26684;。$ sh -x nusers&#43; who&#43; wc -l
也可以在脚本里,用set -x命令打开执行跟踪,然后再用set &#43;x命令关闭。$ cat > trace1.sh#! /bin/shset -xecho 1st echoset &#43;xecho 2nd echo^D$ chmod &#43;x trace1.sh$ ./trace1.sh&#43; echo 1st echo1st echo&#43; set &#43;x2nd echo

         版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-130858-1-1.html 上篇帖子: Shell彩色化 下篇帖子: Windows Shell编程参考网址列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表