﻿﻿<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>帮助信息-动天数据 &#187; shell脚本编程</title>
	<atom:link href="http://www.583idc.com/news/?feed=rss2&#038;tag=shell%E8%84%9A%E6%9C%AC%E7%BC%96%E7%A8%8B" rel="self" type="application/rss+xml" />
	<link>http://www.583idc.com/news</link>
	<description>提供虚拟主机帮助信息</description>
	<lastBuildDate>Mon, 30 Oct 2023 02:58:59 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.41</generator>
	<item>
		<title>shell脚本编程 	linux shell编程实例</title>
		<link>http://www.583idc.com/news/?p=1670</link>
		<comments>http://www.583idc.com/news/?p=1670#comments</comments>
		<pubDate>Wed, 13 Dec 2017 09:03:18 +0000</pubDate>
		<dc:creator><![CDATA[dthost]]></dc:creator>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[shell脚本编程]]></category>

		<guid isPermaLink="false">http://www.583idc.com/news/?p=1670</guid>
		<description><![CDATA[您好，欢迎来到“C语言中文网--&#62;Shell专题”，您将享受到免费的Shell教程和学习资料！ Shel [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>您好，欢迎来到“C语言中文网--&gt;Shell专题”，您将享受到免费的Shell教程和学习资料！</h2>
<h2><img src="http://www.linuxidc.com/upload/2015_02/15020216588722.jpg" alt="《Linux命令行与Shell脚本编程大全》第2版 PDF中文版" align="center" /><br data-filtered="filtered" /><br data-filtered="filtered" />Shell 诞生于 Unix，是与 Unix/Linux 交互的工具，单独地学习 Shell 是没有意义的，请先参考Unix/Linux入门教程，了解 Unix/Lunix 基础。<br data-filtered="filtered" /><br data-filtered="filtered" />近几年来，Shell一直被忽略，是一个不受重视的脚本语言。Shell虽然是Unix的第一个脚本语言，但它是相当优秀的。它结合了延展性与效率，持续保有独具的特色，并不断的被改良，使它多年来能与那些花招很多的脚本语言保持抗衡。<br data-filtered="filtered" /><br data-filtered="filtered" />Shell需要依赖其他程序才能完成大部分的工作，这或许是它的缺陷，但它不容置疑的长处是：简洁的脚本语言标记方式，而且比C语言编写的程序执行更快、更有效率。<br data-filtered="filtered" /><br data-filtered="filtered" />C语言中文网以通俗易懂的语言向您讲解Shell编程，让您在最短的时间内快速掌握Shell，编写出实用的程序和代码。<br data-filtered="filtered" /><br data-filtered="filtered" />为了让您尽快体验最新技术，我们的教程将不断更新，保持与时俱进，请及时关注。您的支持是我们前进的动力！<br data-filtered="filtered" /><br data-filtered="filtered" />说明：C语言中文网的文章由团队成员翻译、编辑和整理，难免有错误和纰漏，请在文章底部留言向我们指出，谢谢。</h2>
<h2>Shell脚本编程的常识</h2>
<p>&nbsp;</p>
<p>现在我们使用的操作系统（Windows、Mac OS、Android、iOS 等）都是带图形界面的，简单直观，容易上手，对专业用户（程序员、网管等）和普通用户（家庭主妇、老年人等）都非常适用；计算机的普及离不开图形界面。<br data-filtered="filtered" /><br data-filtered="filtered" />然而在计算机的早期并没有图形界面，我们只能通过一个一个地命令来控制计算机，这些命令有成百上千之多，且不说记住这些命令非常困难，每天面对没有任何色彩的“黑屏”本身就是一件枯燥的事情；这个时候的计算机还远远谈不上炫酷和普及，只有专业人员才能使用。</p>
<div><img src="http://c.biancheng.net/cpp/uploads/allimg/170629/1-1F629161033F4.jpg" alt="" /></div>
<div>图：早期的电脑，都是“黑纸白字”</div>
<blockquote><p>猛击《带你逛西雅图活电脑博物馆》可以欣赏更多早期的计算机。</p></blockquote>
<p>对于图形界面，用户点击某个图标就能启动某个程序；对于命令行，用户输入某个程序的名字（可以看做一个命令）就能启动某个程序。这两者的基本过程都是类似的，都需要查找程序在硬盘上的安装位置，然后将它们加载到内存运行。</p>
<blockquote><p>关于程序的运行原理，请猛击《载入内存，让程序运行起来》。</p></blockquote>
<p>换句话说，图形界面和命令行要达到的目的是一样的，都是让用户控制计算机。<br data-filtered="filtered" /><br data-filtered="filtered" />然而，真正能够控制计算机硬件（CPU、内存、显示器等）的只有操作系统内核（Kernel），图形界面和命令行只是架设在用户和内核之间的一座桥梁。<br data-filtered="filtered" /><br data-filtered="filtered" />由于安全、复杂、繁琐等原因，用户不能直接接触内核（也没有必要），需要另外再开发一个程序，让用户直接使用这个程序；该程序的作用就是接收用户的操作（点击图标、输入命令），并进行简单的处理，然后再传递给内核。如此一来，用户和内核之间就多了一层“代理”，这层“代理”既简化了用户的操作，也保护了内核。<br data-filtered="filtered" /><br data-filtered="filtered" />用户界面和命令行就是这个另外开发的程序，就是这层“代理”。在Linux下，这个命令行程序叫做 <strong>Shell</strong>。<br data-filtered="filtered" /><br data-filtered="filtered" />Shell 除了能解释用户输入的命令，将它传递给内核，还可以：</p>
<ul>
<li>调用其他程序，给其他程序传递数据或参数，并获取程序的处理结果；</li>
<li>在多个程序之间传递数据，把一个程序的输出作为另一个程序的输入；</li>
<li>Shell 本身也可以被其他程序调用。</li>
</ul>
<p><br data-filtered="filtered" />由此可见，Shell 是将内核、程序和用户连接了起来。<br data-filtered="filtered" /><br data-filtered="filtered" />Shell 本身支持的命令并不多，但是它可以调用其他的程序，每个程序就是一个命令，这使得 Shell 命令的数量可以无限扩展，其结果就是 Shell 的功能非常强大，完全能够胜任 Linux 的日常管理工作，如文本或字符串检索、文件的查找或创建、大规模软件的自动部署、更改系统设置、监控服务器性能、发送报警邮件、抓取网页内容、压缩文件等。<br data-filtered="filtered" /><br data-filtered="filtered" />Shell 并不是简单的堆砌命令，我们还可以在 Shell 中编程，这和使用 C/C++、Java、Python 等常见的编程语言并没有什么两样。<br data-filtered="filtered" /><br data-filtered="filtered" />Shell 虽然没有 C/C++、Java、Python 等强大，但也支持了基本的编程元素，例如：</p>
<ul>
<li>if...else 选择结构，switch...case 开关语句，for、while、until 循环；</li>
<li>变量、数组、字符串、注释、加减乘除、逻辑运算等概念；</li>
<li>函数，包括用户自定义的函数和内置函数（例如 printf、export、eval 等）。</li>
</ul>
<p><br data-filtered="filtered" />站在这个角度讲，Shell 也是一种编程语言，它的编译器（解释器）是 Shell 这个程序。我们平时所说的 Shell，有时候是指连接用户和内核的这个程序，有时候又是指 Shell 编程。<br data-filtered="filtered" /><br data-filtered="filtered" />Shell 主要用来开发一些实用的、自动化的小工具，而不是用来开发具有复杂业务逻辑的中大型软件，例如检测计算机的硬件参数、一键搭建Web开发环境、日志分析等，Shell 都非常合适。<br data-filtered="filtered" /><br data-filtered="filtered" />使用 Shell 的熟练程度反映了用户对 Linux 的掌握程度，运维工程师、网络管理员、程序员都应该学习 Shell。<br data-filtered="filtered" /><br data-filtered="filtered" />尤其是 Linux 运维工程师，Shell 更是必不可少的，是必须掌握的技能，它使得我们能够自动化地管理服务器集群，否则你就得一个一个地登录所有的服务器，对每一台服务器都进行相同的设置，而这些服务器可能有成百上千之多，会浪费大量的时间在重复性的工作上。</p>
<h2>Shell 是一种脚本语言</h2>
<p>任何代码最终都要被“翻译”成二进制的形式才能在计算机中执行。<br data-filtered="filtered" /><br data-filtered="filtered" />有的编程语言，如 C/C++、Pascal、Go语言、汇编等，必须在程序运行之前将所有代码都翻译成二进制形式，也就是生成可执行文件，用户拿到的是最终生成的可执行文件，看不到源码。<br data-filtered="filtered" /><br data-filtered="filtered" />这个过程叫做编译（Compile），这样的编程语言叫做编译型语言，完成编译过程的软件叫做编译器（Compiler）。<br data-filtered="filtered" /><br data-filtered="filtered" />而有的编程语言，如 Shell、JavaScript、Python、PHP等，需要一边执行一边翻译，不会生成任何可执行文件，用户必须拿到源码才能运行程序。程序运行后会即时翻译，翻译完一部分执行一部分，不用等到所有代码都翻译完。<br data-filtered="filtered" /><br data-filtered="filtered" />这个过程叫做解释，这样的编程语言叫做解释型语言或者脚本语言（Script），完成解释过程的软件叫做解释器。<br data-filtered="filtered" /><br data-filtered="filtered" />编译型语言的优点是执行速度快、对硬件要求低、保密性好，适合开发操作系统、大型应用程序、数据库等。<br data-filtered="filtered" /><br data-filtered="filtered" />脚本语言的优点是使用灵活、部署容易、跨平台性好，非常适合Web开发以及小工具的制作。<br data-filtered="filtered" /><br data-filtered="filtered" />Shell 就是一种脚本语言，我们编写完源码后不用编译，直接运行源码即可。</p>
<p>（这些往往是经常用到，但是各种网络上的材料都语焉不详的东西，个人认为比较有用）</p>
<h3>七种文件类型</h3>
<p>d            目录                                                       l             符号链接</p>
<p>s             套接字文件                                           b            块设备文件</p>
<p>c            字符设备文件                                       p            命名管道文件</p>
<p>-             普通文件</p>
<h3>正则表达式</h3>
<p>从一个文件或命令输出中抽取或过滤文本时。可使用正则表达式（RE），正则表达式是一些特殊或不很特殊的字符串模式的集合。</p>
<p>基本的元字符集：</p>
<p>^                   只匹配行首。</p>
<p>$                   只匹配行尾。</p>
<p>*                   一个单字符后紧跟*，匹配0个或多个此单字符。</p>
<p>[]                   匹配[]内字符，可以是一个单字符，也可以是字符序列。可以使</p>
<p>用-来表示[]内范围，如[1-5]等价于[1,2,3,4,5]。</p>
<p>\                    屏蔽一个元字符的特殊含义，如\$表示字符$，而不表示匹配行</p>
<p>尾。</p>
<p>.                 匹配任意单字符。</p>
<p>pattern\{n\}   匹配pattern出现的次数n</p>
<p>pattern\{n,\}m匹配pattern出现的次数，但表示次数最少为n</p>
<p>pattern\{n,m\} 匹配pattern出现的次数在n与m之间（n，m为0－255）</p>
<p>几个常见的例子：</p>
<p>显示可执行的文件：ls –l | grep …x...x..x</p>
<p>只显示文件夹：ls –l | grep  ^d</p>
<p>匹配所有的空行：^$</p>
<p>匹配所有的单词：[A-Z a-z]*</p>
<p>匹配任一非字母型字符：[^A-Z a-z]</p>
<p>包含八个字符的行：^……..$(8个.)</p>
<h3>字符类描述</h3>
<p>以下是可用字符类的相当完整的列表：</p>
<p>[:alnum:] 字母数字 [a-z A-Z 0-9]</p>
<p>[:alpha:] 字母 [a-z A-Z]</p>
<p>[:blank:] 空格或制表键</p>
<p>[:cntrl:] 任何控制字符</p>
<p>[:digit:] 数字 [0-9]</p>
<p>[:graph:] 任何可视字符（无空格）</p>
<p>[:lower:] 小写 [a-z]</p>
<p>[:print:] 非控制字符</p>
<p>[:punct:] 标点字符</p>
<p>[:space:] 空格</p>
<p>[:upper:] 大写 [A-Z]</p>
<p>[:xdigit:] 十六进制数字 [0-9 a-f A-F]</p>
<p>尽可能使用字符类是很有利的，因为它们可以更好地适应非英语 locale（包括某些必需的重音字符等等）.</p>
<h3>shell的引号类型</h3>
<p>shell共有四种引用类型：</p>
<p>“ ”          双引号</p>
<p>‘ ’           单引号</p>
<p>` `         反引号</p>
<p>\            反斜线</p>
<p>l        “ ” 可引用除$、` 、\ 、外的任意字符或字符串，“ ”中的变量能够正常显示变量值。</p>
<p>l        ‘ ’与“ ”类似，不同在于shell会忽略任何的引用值。</p>
<p>例如： GIRL=‘girl’</p>
<p>echo “The ‘$GIRL’ did well”</p>
<p>则打印：The ‘girl’ did well</p>
<p>l        ` `用于设置系统命令的输出到变量，shell会将` `中的内容作为一个系统命令并执行质。</p>
<p>例如：echo `date` 则打印当前的系统时间。</p>
<p>l        \ 用来屏蔽特殊含义的字符：&amp;  *  +  ^  $  `  “  |  ?</p>
<p>例如：expr 12 \* 12 将输出144</p>
<h3>变量设置时的不同模式：</h3>
<p>valiable_name=value           设置实际值到 variable_name中</p>
<p>valiable_name+value           如果设置了variable_name，则重设其值</p>
<p>valiable_name:?value           如果未设置variable_name，则先显示未定义用户错误信息</p>
<p>valiable_name?value           如果未设置variable_name，则显示系统错误信息</p>
<p>valiable_name:=value   如果未设置variable_name，则设置其值</p>
<p>valiable_name-value            同上，但取值并不设置到variable_name</p>
<h3>条件测试</h3>
<p>test命令用于测试字符串、文件状态和数字，expr测试和执行数值输出。</p>
<p>Test格式：test condition 或 [ condition ](需要特别注意的是condition的两边都要有一个空格，否则会报错)，test命令返回0表示成功。</p>
<p>l        下面将分别描述test的三种测试：</p>
<p>n        文件状态测试(常用的)</p>
<p>-d           测试是否文件夹</p>
<p>-f            测试是否一般文件</p>
<p>-L          测试是否链接文件</p>
<p>-r           测试文件是否可读</p>
<p>-w         测试文件是否可写</p>
<p>-x           测试文件是否可执行</p>
<p>-s           测试文件是否非空</p>
<p>n        字符串测试</p>
<p>五种格式： test  “string”</p>
<p>test  string_operator  “string”</p>
<p>test  “string”  string_operator  “string”</p>
<p>[ string_operator  “string” ]</p>
<p>[ “string”  string_operator  “string” ]</p>
<p>其中string_operator可以为：       =     两字符串相等</p>
<p>!=    两字符串不等</p>
<p>-z   空串</p>
<p>-n   非空串</p>
<p>n        数值测试</p>
<p>两种格式： “number”  number_operator  “number”</p>
<p>[ “number”  number_operator  “number” ]</p>
<p>其中：number_operator 可以为：-eq  、-ne、-gt、-lt、-ge</p>
<p>例如：  NUMBER=130</p>
<p>[ “990”  –le  “995”  –a  “NUMBER”  -gt  “133” ]</p>
<p>(其中-a表示前后结果相“与”)</p>
<p>l        expr命令一般用于整数值，但也可以用于字符串。</p>
<p>n        格式：  expr srgument operator operator argument</p>
<p>例如：  expr 10 + 10</p>
<p>expr 10 ^ 2 (10的平方)</p>
<p>expr $value + 10</p>
<p>n        增量计数――expr在循环中最基本的用法</p>
<p>例如：  LOOP=0</p>
<p>LOOP=`expr $LOOP + 1`</p>
<p>n        模式匹配：通过指定的冒号选项计算字符串中的字符数</p>
<p>例如：  value=account.doc</p>
<p>expr $value : `\(.*\).doc`</p>
<p>输出 account</p>
<p>每一个在UNIX/Linux上工作的程序员可能都擅长shell脚本编程。但大家解决问题的方式却不尽相同，这要取决于对专业知识的掌握程度、使用命令的种类、看待问题的方式等等。对于那些处在shell脚本编程初级阶段的程序员来说，遵循一些恰当的做法可以帮助你更快、更好的学习这些编程技巧。下面，我们就来讨论这些能帮助你学习shell脚本编程的方法吧。</p>
<p><strong>0、多动手</strong></p>
<p>你想学习shell脚本编程，这很不错。于是你拿了一本书开始学习。一些人会首先通读整本教材后再上机练习。这种方法可能适用于一些人，但我却不太看好它。我的建议是，仅仅学一些最基础的能够让你开始编码的知识就可以了。之后，动手写一些简单的程序吧。一旦你由于知识上的欠缺而不得不停止时，再回到书本上去读你想要了解的那部分，然后继续做你的项目。如此周而复始，不断提高你的水平。这种边学边做的方法曾让我受益良多。</p>
<p><strong>1、善用命令提示符</strong></p>
<p>有时候，我们写的脚本中有一些错误。我们修改错误，运行脚本，但系统再次报错。并且这个改错报错的过程可能会发生很多次。碰到这些情况，首先需要找到有问题的行或命令，这可以通过一些调试语句来轻松做到。一旦发现这条语句，尝试在命令提示符下执行相同的语句。如果它在命令提示符下开始正常运行，你就可以容易的推断出它不能正常运行的原因了。可能是由于某些错误输入的命令，或者是某些环境变量不匹配，或者是从不同的地方引用了某个二进制文件等等。这种方法会让调试变得简单易行。</p>
<p><img class="aligncenter size-full wp-image-16605" title="关于 shell 脚本编程的10 个最佳实践" src="http://jbcdn2.b0.upaiyun.com/2012/04/your-first-shell-script.jpg" alt="关于 shell 脚本编程的10 个最佳实践" width="280" height="280" /></p>
<p><strong>2、考虑问题要全面</strong></p>
<p>现在我们来看个问题。你想到了关于某个问题的解决方案，但这个解决方案只适用于处理小型文件。可是当处理比较大的文件时，你该怎么办？举个例子，我们想要得到一个文件的第一行内容：</p>
<div id="crayon-5a30ef17838e9678932522" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always">
<div class="crayon-toolbar" data-settings=" show">
<div class="crayon-tools">
<div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"></div>
<div class="crayon-button crayon-plain-button" title="纯文本显示代码"></div>
<div class="crayon-button crayon-wrap-button" title="切换自动换行"></div>
<div class="crayon-button crayon-copy-button" title="复制代码"></div>
<div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"></div>
<p><span class="crayon-language">Shell</span></div>
</div>
<div class="crayon-plain-wrap"></div>
<div class="crayon-main">
<table class="crayon-table">
<tbody>
<tr class="crayon-row">
<td class="crayon-nums " data-settings="show">
<div class="crayon-nums-content">
<div class="crayon-num" data-line="crayon-5a30ef17838e9678932522-1">1</div>
</div>
</td>
<td class="crayon-code">
<div class="crayon-pre">
<div id="crayon-5a30ef17838e9678932522-1" class="crayon-line"><span class="crayon-r">sed</span> <span class="crayon-o">-</span><span class="crayon-i">n</span> <span class="crayon-s">'1p'</span> <span class="crayon-r">file</span></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>这条语句当然会给出你想要的第一行内容。可是如果处理的文件包含上百万条记录呢？尽管上面的那条sed命令可以输出文件的第一行内容，但是想要处理大型文件一定会带来性能上的问题。</p>
<p>解决办法：</p>
<div id="crayon-5a30ef17838f6843516554" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always">
<div class="crayon-toolbar" data-settings=" show">
<div class="crayon-tools">
<div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"></div>
<div class="crayon-button crayon-plain-button" title="纯文本显示代码"></div>
<div class="crayon-button crayon-wrap-button" title="切换自动换行"></div>
<div class="crayon-button crayon-copy-button" title="复制代码"></div>
<div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"></div>
<p><span class="crayon-language">Shell</span></div>
</div>
<div class="crayon-plain-wrap"></div>
<div class="crayon-main">
<table class="crayon-table">
<tbody>
<tr class="crayon-row">
<td class="crayon-nums " data-settings="show">
<div class="crayon-nums-content">
<div class="crayon-num" data-line="crayon-5a30ef17838f6843516554-1">1</div>
</div>
</td>
<td class="crayon-code">
<div class="crayon-pre">
<div id="crayon-5a30ef17838f6843516554-1" class="crayon-line"><span class="crayon-r">sed</span> <span class="crayon-o">-</span><span class="crayon-i">n</span> <span class="crayon-s">'1p;1q'</span> <span class="crayon-r">file</span></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>这条命令将只输出第一行，同时退出程序。</p>
<p><strong>3、经常尝试不同的方法</strong></p>
<p>你在写脚本时碰到一个问题，然后你找到了一种独特的解决方法。下一次你偶然又碰到类似的问题，这时，不要再用以前你用过的方法来解决。试试另外一种方法吧。如果某一天再次遇到这种情况，再试试其它方法。</p>
<p>例如：</p>
<div id="crayon-5a30ef17838fb854160027" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always">
<div class="crayon-toolbar" data-settings=" show">
<div class="crayon-tools">
<div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"></div>
<div class="crayon-button crayon-plain-button" title="纯文本显示代码"></div>
<div class="crayon-button crayon-wrap-button" title="切换自动换行"></div>
<div class="crayon-button crayon-copy-button" title="复制代码"></div>
<div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"></div>
<p><span class="crayon-language">Shell</span></div>
</div>
<div class="crayon-plain-wrap"></div>
<div class="crayon-main">
<table class="crayon-table">
<tbody>
<tr class="crayon-row">
<td class="crayon-nums " data-settings="show">
<div class="crayon-nums-content">
<div class="crayon-num" data-line="crayon-5a30ef17838fb854160027-1">1</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a30ef17838fb854160027-2">2</div>
<div class="crayon-num" data-line="crayon-5a30ef17838fb854160027-3">3</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a30ef17838fb854160027-4">4</div>
</div>
</td>
<td class="crayon-code">
<div class="crayon-pre">
<div id="crayon-5a30ef17838fb854160027-1" class="crayon-line"><span class="crayon-st">if</span> <span class="crayon-sy">[</span> <span class="crayon-sy">$</span><span class="crayon-sy">?</span> <span class="crayon-o">-</span><span class="crayon-i">eq</span> <span class="crayon-cn">0</span> <span class="crayon-sy">]</span></div>
<div id="crayon-5a30ef17838fb854160027-2" class="crayon-line crayon-striped-line"><span class="crayon-st">then</span></div>
<div id="crayon-5a30ef17838fb854160027-3" class="crayon-line"><span class="crayon-h">   </span><span class="crayon-r">echo</span> <span class="crayon-s">"Success"</span></div>
<div id="crayon-5a30ef17838fb854160027-4" class="crayon-line crayon-striped-line"><span class="crayon-st">fi</span></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>另一种方法：</p>
<div id="crayon-5a30ef17838ff978530741" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always">
<div class="crayon-toolbar" data-settings=" show">
<div class="crayon-tools">
<div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"></div>
<div class="crayon-button crayon-plain-button" title="纯文本显示代码"></div>
<div class="crayon-button crayon-wrap-button" title="切换自动换行"></div>
<div class="crayon-button crayon-copy-button" title="复制代码"></div>
<div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"></div>
<p><span class="crayon-language">Shell</span></div>
</div>
<div class="crayon-plain-wrap"></div>
<div class="crayon-main">
<table class="crayon-table">
<tbody>
<tr class="crayon-row">
<td class="crayon-nums " data-settings="show">
<div class="crayon-nums-content">
<div class="crayon-num" data-line="crayon-5a30ef17838ff978530741-1">1</div>
</div>
</td>
<td class="crayon-code">
<div class="crayon-pre">
<div id="crayon-5a30ef17838ff978530741-1" class="crayon-line"><span class="crayon-sy">[</span> <span class="crayon-sy">$</span><span class="crayon-sy">?</span> <span class="crayon-o">-</span><span class="crayon-i">eq</span> <span class="crayon-cn">0</span> <span class="crayon-sy">]</span> <span class="crayon-o">&amp;&amp;</span> <span class="crayon-r">echo</span> <span class="crayon-s">"Success"</span></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>现在你可能会明白这个博客里会有那么多以“……的不同解决方法”为题的文章了吧。所有这些文章的目的都是用来帮助订阅这个博客的开发者开阔视野，打开思路。</p>
<p><strong>4、快速编码</strong></p>
<p>脚本可以节省我们的时间，提高生产力。可是，难道我们花在写脚本和测试上的时间还少吗？我们想写一个脚本，于是打开一个文件，写下代码，保存文件，之后运行脚本，系统报错，我们再打开文件修改、保存、运行……在这个过程中会花费很多时间。在此前的一篇题为《如何快速写shell脚本》的文章里，你可以学会如何编写脚本和测试正在运行中的脚本，而不用再回顾命令提示符。这些方法可以加快编码的速度。当我写脚本的时候，我总是使用这些方法。而且我可以很肯定的说，它们帮我节约了不少时间。</p>
<p><strong>5、经常使用内部命令</strong></p>
<p>无论碰到哪种情况，请尽量考虑使用内部命令而不是外部命令。在此前的一篇题为《内部命令和外部命令》的文章里，我们可以看到二者间的差异。用内部命令对你永远都有好处。根据正在处理的输入文件的大小，内部命令可以在性能方面为你节省很多。虽然你并不总是有这样选择内部命令抑或外部命令的机会，但在某些情况下，你一定能做出正确的选择。</p>
<p><strong>6、没有必要使用cat命令</strong></p>
<p>这是我们经常在论坛里讨论的话题之一。没有必要使用cat命令指的是在有些时候，我们会发现根本没有必要使用cat命令。有时候，使用了多余的cat命令会让你的代码看起来很丑陋，而且还会带来性能上的问题。</p>
<p>例如：</p>
<div id="crayon-5a30ef1783903542428069" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always">
<div class="crayon-toolbar" data-settings=" show">
<div class="crayon-tools">
<div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"></div>
<div class="crayon-button crayon-plain-button" title="纯文本显示代码"></div>
<div class="crayon-button crayon-wrap-button" title="切换自动换行"></div>
<div class="crayon-button crayon-copy-button" title="复制代码"></div>
<div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"></div>
<p><span class="crayon-language">Shell</span></div>
</div>
<div class="crayon-plain-wrap"></div>
<div class="crayon-main">
<table class="crayon-table">
<tbody>
<tr class="crayon-row">
<td class="crayon-nums " data-settings="show">
<div class="crayon-nums-content">
<div class="crayon-num" data-line="crayon-5a30ef1783903542428069-1">1</div>
</div>
</td>
<td class="crayon-code">
<div class="crayon-pre">
<div id="crayon-5a30ef1783903542428069-1" class="crayon-line"><span class="crayon-sy">$</span> <span class="crayon-r">cat</span> <span class="crayon-o">/</span><span class="crayon-v">etc</span><span class="crayon-o">/</span><span class="crayon-v">passwd</span> <span class="crayon-o">|</span> <span class="crayon-r">grep</span> <span class="crayon-v">guru</span></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>正确的方法应该是：</p>
<div id="crayon-5a30ef1783906944800528" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always">
<div class="crayon-toolbar" data-settings=" show">
<div class="crayon-tools">
<div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"></div>
<div class="crayon-button crayon-plain-button" title="纯文本显示代码"></div>
<div class="crayon-button crayon-wrap-button" title="切换自动换行"></div>
<div class="crayon-button crayon-copy-button" title="复制代码"></div>
<div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"></div>
<p><span class="crayon-language">Shell</span></div>
</div>
<div class="crayon-plain-wrap"></div>
<div class="crayon-main">
<table class="crayon-table">
<tbody>
<tr class="crayon-row">
<td class="crayon-nums " data-settings="show">
<div class="crayon-nums-content">
<div class="crayon-num" data-line="crayon-5a30ef1783906944800528-1">1</div>
</div>
</td>
<td class="crayon-code">
<div class="crayon-pre">
<div id="crayon-5a30ef1783906944800528-1" class="crayon-line"><span class="crayon-sy">$</span> <span class="crayon-r">grep</span> <span class="crayon-v">guru</span> <span class="crayon-o">/</span><span class="crayon-v">etc</span><span class="crayon-o">/</span><span class="crayon-v">passwd</span></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p><strong id="">7、仔细阅读错误信息</strong></p>
<p>程序员常犯的一个错误是：当我们敲入的命令报错后，我们中的大多数人只是对错误信息一瞥而过，而不会去认真的读一读。很多时候，错误信息里就包含了解决办法。更重要的是，有时候我们修改了某个错误并再次运行后，系统依旧会报错。然后我们再次修改，但系统再次报错。这可能会持续很长时间。但实际上，旧的错误可能已经被纠正，只是由于出现了其它一些新错误才导致系统再次报错。而我们依旧在怀疑为什么修改好的代码依然不能正常运行。因此，请你养成仔细阅读错误信息的习惯。</p>
<p><strong>8、尽量避免臃肿的命令</strong></p>
<p>你正在尝试去从一个大的文件中筛选某条信息。接下来你可能写一大堆命令来实现这一功能。可是，尽管你将得到正确的结果，你写的命令却不够好，且晦涩难懂。因此，我们应该尽量避免这种情况发生。下面这个例子就是代码优化的好例子。</p>
<p>从程序员的角度来看， Shell本身是一种用C语言编写的程序，从用户的角度来看，Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行，又可以利用 Shell脚本编程，完成更加复杂的操作。在Linux GUI日益完善的今天，在系统管理等领域，Shell编程仍然起着不可忽视的作用。深入地了解和熟练地掌握Shell编程，是每一个Linux用户的必修 功课之一。</p>
<p>Linux的Shell种类众多，常见的有：Bourne Shell（/usr/bin/sh或/bin/sh）、Bourne Again Shell（/bin/bash）、C Shell（/usr/bin/csh）、K Shell（/usr/bin/ksh）、Shell for Root（/sbin/sh），等等。不同的Shell语言的语法有所不同，所以不能交换使用。每种Shell都有其特色之处，基本上，掌握其中任何一种 就足够了。在本文中，我们关注的重点是Bash，也就是Bourne Again Shell，由于易用和免费，Bash在日常工作中被广泛使用；同时，Bash也是大多数Linux系统默认的Shell。在一般情况下，人们并不区分 Bourne Shell和Bourne Again Shell，所以，在下面的文字中，我们可以看到#!/bin/sh，它同样也可以改为#!/bin/bash。</p>
<p>利用vi等文本编辑器编写Shell脚本的格式是固定的，如下：</p>
<div class="jb51code">
<div>
<div id="highlighter_186418" class="syntaxhighlighter  bash">
<div class="toolbar">?</div>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="bash preprocessor bold">#!/bin/sh</code></div>
<div class="line number2 index1 alt1"><code class="bash comments">#comments</code></div>
<div class="line number3 index2 alt2"><code class="bash plain">Your commands go here</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>首行中的符号#!告诉系统其后路径所指定的程序即是解释此脚本文件的Shell程 序。如果首行没有这句话，在执行脚本文件的时候，将会出现错误。后续的部分就是主程序，Shell脚本像高级语言一样，也有变量赋值，也有控制语句。除第 一行外，以#开头的行就是注释行，直到此行的结束。如果一行未完成，可以在行尾加上"，这个符号表明下一行与此行会合并为同一行。</p>
<p>编辑完毕，将脚本存盘为filename.sh，文件名后缀sh表明这是一个Bash脚本文件。执行脚本的时候，要先将脚本文件的属性改为可执行的：</p>
<div class="jb51code">
<div>
<div id="highlighter_220351" class="syntaxhighlighter  bash">
<div class="toolbar">?</div>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="bash functions">chmod</code> <code class="bash plain">+x filename.sh</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>执行脚本的方法是：</p>
<div class="jb51code">
<div>
<div id="highlighter_671164" class="syntaxhighlighter  bash">
<div class="toolbar">?</div>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="bash plain">.</code><code class="bash plain">/filename</code><code class="bash plain">.sh</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>下面我们从经典的“hello world”入手，看一看最简单的Shell脚本的模样。</p>
<div class="jb51code">
<div>
<div id="highlighter_341434" class="syntaxhighlighter  bash">
<div class="toolbar">?</div>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="bash preprocessor bold">#!/bin/sh</code></div>
<div class="line number2 index1 alt1"><code class="bash comments">#print hello world in the console window</code></div>
<div class="line number3 index2 alt2"><code class="bash plain">a = </code><code class="bash string">"hello world"</code></div>
<div class="line number4 index3 alt1"><code class="bash functions">echo</code> <code class="bash plain">$a</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>Shell Script是一种弱类型语言，使用变量的时候无需首先声明其类型。新的变量会在本地数据区分配内存进行存储，这个变量归当前的Shell所有，任何子进 程都不能访问本地变量。这些变量与环境变量不同，环境变量被存储在另一内存区，叫做用户环境区，这块内存中的变量可以被子进程访问。变量赋值的方式是：</p>
<div class="jb51code">
<div>
<div id="highlighter_418844" class="syntaxhighlighter  bash">
<div class="toolbar">?</div>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="bash plain">variable_name = variable_value</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>如果对一个已经有值的变量赋值，新值将取代旧值。取值的时候要在变量名前加$，$variable_name可以在引号中使用，这一点和其他高级语言是明显不同的。如果出现混淆的情况，可以使用花括号来区分，例如：</p>
<p>echo "Hi, $as"</p>
<p>就不会输出“Hi, hello worlds”，而是输出“Hi，”。这是因为Shell把$as当成一个变量，而$as未被赋值，其值为空。正确的方法是：</p>
<p>echo "Hi, ${a}s"</p>
<p>单引号中的变量不会进行变量替换操作。 <br data-filtered="filtered" />关于变量，还需要知道几个与其相关的Linux命令。</p>
<p>env用于显示用户环境区中的变量及其取值；set用于显示本地数据区和用户环境区中的变量及其取值；unset用于删除指定变量当前的取值，该值将被指定为NULL；export命令用于将本地数据区中的变量转移到用户环境区。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.583idc.com/news/?feed=rss2&#038;p=1670</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
