linux程序设计——shell程序设计(第二章)

第二章    shell程序设计

本章介绍以下内容:

什么是shell

基本思路

微妙的语法:变量,条件判断和程序控制

命令列表

函数

命令和命令的执行

here文档

调试

grep命令和正则表达式

find命令

shell执行shell程序,这些程序通常称为脚本,它们是在运行时解释执行的。这使得调试工作比较容易进行,因为可以逐行地执行指令,而且节省了重新编译的时间。然而,这也使得shell不适合用来完成时间紧迫型和处理器忙碌型的任务。

UNIX架构非常依赖于代码的高度可重用性,如果你编写了一个小巧而简单的工具,其他人就可以将它作为一根链条上的某个环节来构成一条命令。

什么是shell

shell是一个作为用户与linux系统间接口的程序,它允许用户向操作系统输入需要执行的命令。这点与windows的命令提示符类似,但是Linxu shell的功能更强大。

shell(bash和csh)以及X视窗系统和其他程序环绕在linux内核的周围。在linux系统中,总是作为/bin/sh安装的标准shell是GNU工具集中的bash。在大多数linux发行版中,默认的shell程序/bin/sh实际上是对程序/bin/bash的一个连接。

可以使用/bin/bash --version查看bash的版本号

2.4管道和重定向

介绍如何对linxu程序的输入输出进行重定向

重定向输出:

$ ls -1 > lsoutput.txt

这条命令把ls命令的输出保存到文件lsoutput.txt中。

文件描述符0代表一个程序的标准输入,文件描述符1代表一个程序的标准输出,文件描述符2代表标准错误输出

>操作符把标准输出重定向到一个文件。在默认情况下,如果该文件已经存在,它的内容将被覆盖

>>操作符将输出内容附加到一个文件中。例如:

$ ps >> lsoutput.txt

这条命令会将ps命令的输出附加到特定文件的尾部。

如果想对标准错误输出进行重定向,需要把重定向的文件描述符编号加载>操作符的前面。因为标准错误输出的文件描述符是2,所以使用2>操作符。当需要丢掉错误信息并阻止它显示在屏幕上时,这个方法很有用。

管道

可以用管道操作符|来连接进程,linux与MS-DOS不同,在linux下通过管道连接的进程可以同时运行,并且随着数据流在它们之间的传递可以自动地进行协调。例如,可以使用sort命令对ps命令的输出进行排序。

如果不使用管道,则必须分几个步骤来完成这个任务,如下所示:

$ ps > psout.txt

$ sort psout.txt > pssort.out

一个更精巧的解决方案是用管道来连接进程,如下所示:

$ ps | sort > pssort.out

作为程序设计语言的shell

编写shell脚本程序有两种方式,可以输入一系列命令让shell交互执行它们,也可以把这些命令保存到一个文件中,然后将这个文件作为程序来调用。

交互式程序

在命令行上直接输入shell脚本是一种测试短小代码段的简单而快捷的方式。

假如想要从大量C语言源文件中查找包含字符串POSIX的文件。与其使用grep命令在每个文件中搜索字符串,然后再分别列出包含该字符串的文件,不如用下面交互式脚本来执行整个操作:

$ for file in *

> do

> if grep -1 POSIX $file

> then

> more $file

> fi

> done

在这个例子中,grep命令输出它找到的包含POSIX字符串的文件,然后more命令将文件的内容显示在屏幕上,最后,返回shell提示符。shell还提供了通配符扩展,通配符×来匹配一个字符串,通配符?来匹配单个字符,而[set]允许匹配方括号中任何一个单个字符,[^set]对方括号中的内容取反,即匹配除给定字符集中字符以外的字符。扩展的花括号{}允许将任意的字符串组放在一个集合中。例如

$ ls my_{finger, toe}s

这个命令将列出文件my_fingers和my_toes,它使用shell来检查当前目录下的每个文件。

有经验的linux用户可能使用另一种更有效的方式来执行这个简单的操作。使用命令:

$ more  ‘grep -l POSIX *‘

或者是命令:

$ more $(grep -l POSIX *)

此外,下面的命令将输出包含POSIX字符串的文件名:

$ grep -1 POSIX* | more

上面的脚本中,shell利用其他命令(如grep和more)来完成主要的工作。shell本身只是允许将几个现有的命令结合在一起,构成一个新的功能强大的命令。

如果每次想要执行一系列命令时,都要经过这么一个过程,非常麻烦。因此只需要将这些命令保存在一个文件中,即我们常说的shell脚本,这样就可以随时执行。

创建脚本

使用vim创建一个包含命令的文件,将其命名为first。

程序中的注释以#符号开始,一直持续到该行的结束。第一行#!/bin/sh,它是一种特殊的注释,#!字符告诉系统同一行上紧跟在它后面的那个参数是用来执行本文件的程序。/bin/sh是默认的shell程序。

exit命令的作用是确保脚本程序能够返回一个有意义的退出码。当程序以交互方式运行时,很少需要检查它的退出码,但是从另一个脚本程序里调用这个脚本程序并查看它是否执行成功,那么返回一个适当的退出码是必要的。

shell程序设计里,0表示成功

一般情况下,Linux和UNIX很少使用文件扩张名来决定文件的类型。大多数预安装的脚本程序并没有使用任何文件扩张名,检查这些文件是否是脚本程序的最好方法是使用file命令,例如file first或者file /bin/bash。

运行脚本文件有两种方法,比较简单的方法是调用shell,并把脚本文件名当成一个参数,如下所示:

$ /bin/sh first

这可以工作,但如果能像对待其他Linxu命令那样,只输入脚本程序的名字就可以调用它就更好了。你可以使用chmod命令来改变这个文件的模式,使得这个文件可以被所有用户执行,如下所示:

$ chmod +x first

然后可以用下面的命令来执行它:

$ first

你可能会看到一条错误信息来告诉你未找到命令。这种情况很可能发生,因为shell环境变量PATH并没有被设置为在当前目录下查找要执行的命令。一种方法是在命令行上直接输入命令PATH=$PATH:.,然后退出登陆后再重新登陆进来。另外,也可以在保存脚本程序的目录中输入命令./first,该命令的作用是把脚本程序的完整的相对路径告诉shell。

用./来指定路径还有另一个好处,它能够保证不会意外执行系统中与你的脚本文件同名的另一个命令。

时间: 2024-10-15 20:18:38

linux程序设计——shell程序设计(第二章)的相关文章

鸟哥的 Linux 私房菜(服务器) 第二章 网络基础概念

鸟哥的 Linux 私房菜(服务器) @(学习笔记)[Linux|Markdown|笔记] [TOC] 第二章 网络基础概念 2.1 网络是个什么玩意儿 OSI 七层协定 分层 负责内容 Layer 1物理层Physical Layer 由于网络媒体只能传送 0 与 1 这种位串,因此物理层必须定义所使用的媒体设备之电压与讯号等, 同时还必须了解数据讯框转成位串的编码方式,最后连接实体媒体并传送/接收位串. Layer 2数据链结层Data-Link Layer 这一层是比较特殊的一个阶层,因为

【深入理解Linux内核】《第二章 内存寻址》笔记 (2014-06-28 12:38)

2.1 内存地址 逻辑地址:段+偏移 线性地址(虚拟地址) 物理地址 2.2硬件中的分段 2.2.1 段选择符和段寄存器 15                                                3  2  1   0 ------------------------------------------------|                                                    |TI |RPL  ||         索引号 

Linux与云计算——第二阶段 第二章:DHCP服务器架设

Linux与云计算--第二阶段Linux服务器架设 第二章:DHCP服务器架设 1.配置DHCP服务器 配置DHCP ( Dynamic Host Configuration Protocol ) 服务器. DHCP使用UDP端口67. [1] 安装并配置DHCP服务器. [[email protected] ~]# yum -y install dhcp [[email protected] ~]# vim /etc/dhcp/dhcpd.conf # 创建一个新文件 # 指定域名 optio

JavaScript高级程序设计学习笔记第二章

1.向 HTML 页面中插入 JavaScript 的主要方法,就是使用<script>元素 2.HTML 4.01中定义了<script>元素的六个属性(方便记忆,可将6个属性分为3组) 第一组: async:可选.表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本.只对外部脚本文件有效.(使用<script>不属于外部脚本) defer:可选.表示脚本可以立即下载,但是延迟到文档完全被解析和显示之后再执行.只对外部脚本文件有效. 第

《挑战程序设计竞赛》第二章

2.1 最基础的穷竭搜索 poj 2386  Lake Counting(裸dfs) 题意:n*m的矩阵 W是水 .是地 问有多少池塘.(池塘的定义是: W通过八个方向连接成的一片算作是一个池塘.) 1 #include <iostream> 2 using namespace std; 3 #include <cstdio> 4 const int maxn = 100 + 5; 5 int n, m; 6 char ma[maxn][maxn]; 7 int dx[] = {-

JavaScript高级程序设计 读书笔记 第二章

<script>元素 直接在页面中嵌入JavaSript代码或包含外部JavaSript文件. 在代码中任何地方不能出现</script>,可通过转义字符'\'解决. 在XHTML中可省略</script>,HTML中不能. 延迟脚本:defer属性(defer="defer"),告诉浏览器立即下载,延迟执行.最好只包含一个延迟脚本. 异步脚本:async属性(async="async"),不让页面等待两个脚本下载和执行,异步加载

《Linux系统编程》第二章笔记(一)

文件I/O 前言 文件概念对于Linux系统的重要性不言而喻,本章主要介绍了内核为文件的创建.读.写.定位等系统调用以及高效的I/O机制.Linux系统为文件操作提供了通用的系列系统调用,使开发人员能够对所有"文件"做相同的操作,同时还提供了ioctl()系统调用对非通用文件操作,fcntl()系统调用对文件描述符做操作. 此外Linux内核为了弥补CPU运算速度和磁盘I/O速度的巨大差异,引入了页缓存.页回写机制.简单来说就是读取文件时多读取一部分并保存在内核缓冲区中,在下次收到读取

201671010105 2016-2017-2《Java程序设计》第一、第二章学习心得

我们大一的时候学习的是C语言程序设计,C语言是面向程序的,而老师也说过我们后面会学习一种面向对象的程序设计语言--Java程序设计,而在二年级开学第一周,我们第一次真正意义上接触到了它. 令人意外的是和往常老师讲学生听不同,这一周我们对Java程序设计第一.第二章的学习完全是自主的,通过一周对Java第一.第二章的学习,心得体会如下: 第一章 Java程序设计概述 1.通过对第一章的学习,对Java有了比较深入的了解,Java和C一样,是一种语言,但它又不止是一种语言,它是一个完整的程序设计平台

《Linux程序设计 第四版》之第二章的最后练习题

这篇文章是<Linux程序设计 第四版>中的第二章的最后练习题(2.8综合应用), 题目是编写一个CD数据库应用程序, 首先:用两个文件来保存存储的数据,一个是title_file.cdb,一个是column_file.cdb! title_file.cdb里面保存的是唱片的基本信息:拥有如下四个字段: CD的目录编号,标题,唱片类型,作曲家或艺术家: column_file.cdb里面保存的是唱片的详细信息即唱片包含的歌曲信息:拥有如下三个字段: CD的目录编号,曲目编号,歌曲名 其次: 有