LINUX快速入门第八章:Shell基础

LINUX快速入门第八章:Shell基础

图片[1]-LINUX快速入门第八章:Shell基础-学吧号

我们平时所说的 Shell 可以理解为 Linux 系统提供给用户的使用界面。Shell 为用户提供了输入命令和参数并可得到命令执行结果的环境。

当一个用户登录 Linux 之后,系统初始化程序 init 就根据 /etc/passwd 文件中的设定,为每个用户运行一个被称为 Shell(外壳)的程序。

确切地说,Shell 是一个命令行解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至编写一些程序。 Shell 处在内核与外层应用程序之间,起着协调用户与系统的一致性、在用户与系统之间进行交互的作用。图 1 是 Linux 系统层次结构图,Shell 接收用户输入的命令,并把用户的命令从类似 abed 的 ASCII 码解释为类似 0101 的机器语言,然后把命令提交到系统内核处理;当内核处理完毕之后,把处理结果再通过 Shell 返回给用户。 换句话说: Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。

Shell 既是一种命令语言,又是一种程序设计语言。 Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。 Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。

Shell 与其他 Linux 命令一样,都是实用程序,但它们之间还是有区别的。一旦用户注册到系统后,Shell 就被系统装入内存并一直运行到用户退出系统为止;而一般命令仅当被调用时,才由系统装入内存执行。 与一般命令相比,Shell 除了是一个命令行解释器,同时还是一门功能强大的编程语言,易编写,易调试,灵活性较强。

作为一种命令级语言,Shell 是解释性的,组合功能很强,与操作系统有密切的关系,可以在 Shell 脚本中直接使用系统命令。大多数 Linux 系统的启动相关文件(一般在 /etc/rc.d 目录下)都是使用 Shell 脚本编写的。 同传统的编程语言一样,Shell 提供了很多特性,这些特性可以使 Shell 脚本编程更为有用,如数据变量、参数传递、判断、流程控制、数据输入和输出、子程序及中断处理等。

说了这么多,其实我们在 Linux 中操作的命令行界面就是 Linux 的 Shell,也就是 Bash,但是我们的图形界面是 Shell 吗?其实从广义讲,图形界面当然也是 Shell,因为它同样用来接收用户的操作,并传递到内核进行处理。不过,这里的 Shell 主要指的是 Bash。 Shell 脚本 Shell 脚本(shell script),是一种为 shell 编写的脚本程序。 业界所说的 shell 通常都是指 shell 脚本,但读者朋友要知道,shell 和 shell script 是两个不同的概念。

由于习惯的原因,简洁起见,本文出现的 “shell编程” 都是指 shell 脚本编程,不是指开发 shell 自身。 Shell的分类 目前 Shell 的版本有很多种,如 Bourne Shell、C Shell、Bash、ksh、tcsh 等,它们各有特点,下面简要介绍一下。 最重要的 Shell 是 Bourne Shell,这个命名是为了纪念此 Shell 的发明者 Steven Bourne。从 1979 年起,UNIX 就开始使用 Boume Shell。

Bourne Shell 的主文件名为 sh,开发人员便以 sh 作为 Bourne Shell 的主要识别名称。 虽然 Linux 与 UNIX 一样,可以支持多种 Shell,但 Boume Shell 的重要地位至今仍然没有改变,许多 UNIX 系统中仍然使用 sh 作为重要的管理工具。它的工作从开机到关机,几乎无所不包。在 Linux 中,用户 Shell 主要是 Bash,但在启动脚本、编辑等很多工作中仍然使用 Bourne Shell。

C Shell 是广为流行的 Shell 变种。C Shell 主要在 BSD 版的 UNIX 系统中使用,发明者是柏克莱大学的 Bill Joy。C Shell 因为其语法和 C 语言类似而得名,这也使得 UNIX 的系统工程师在学习 C Shell 时感到相当方便。

Bourne Shell 和 C Shell 形成了 Shell 的两大主流派别,后来的变种大都吸取这两种 Shell 的特点,如 Korn、 tcsh 及 Bash。 Bash Shell 是 GNU 计划的重要工具之一,也是 GNU 系统中标准的 Shell。Bash 与 sh 兼容,所以许多早期开发出来的 Bourne Shell 程序都可以继续在 Bash 中运行。

现在使用的 Linux 就使用 Bash 作为用户的基本 Shell。 Bash 于 1988 年发布,并在 1995-1996年推出Bash 2.0。在这之前,广为使用的版本是1.14,Bash 2.0增加了许多新的功能,以及具备更好的兼容性。表 2 中详细列出了各版本的具体情况。

注意,Shell 的两种主要语法类型有 Bourne 和 C,这两种语法彼此不兼容。Boume 家族主要包括 sh、ksh、Bash、psh、zsh;C 家族主要包括 csh、tcsh(Bash 和 zsh 在不同程序上支持 csh 的语法)。 本章讲述的脚本编程就是在 Bash 环境中进行的。

不过,在 Linux 中除了可以支持 Bash,还可以支持很多其他的 Shell。我们可以通过 /etc/shells 文件来査询 Linux 支持的 Shell。命令如下: 在 Linux 中,这些 Shell 是可以任意切换的,命令如下: 用户信息文件 /etc/passwd 的最后一列就是这个用户的登录 Shell。命令如下: 大家可以看到,root 用户和其他可以登录系统的普通用户的登录 Shell 都是 /bin/bash,也就是 Linux 的标准 Shell,所以这些用户登录之后可以执行权限允许范围内的所有命令。

不过,所有的系统用户(伪用户)因为登录 Shell 是 /sbin/ndogin,所以不能登录系统。

如何编写一个shell脚本

图片[2]-LINUX快速入门第八章:Shell基础-学吧号

如何编写一个shell脚本本文结合大量实例阐述如何编写一个shell脚本。为什么要进行shell编程在Linux系统中,虽然有各种各样的图形化接口工具,但是sell仍然是一个非常灵活的工具。

Shell不仅仅是命令的收集,而且是一门非常棒的编程语言。

您可以通过使用shell使大量的任务自动化,shell特别擅长系统管理任务,尤其适合那些易用性、可维护性和便携性比效率更重要的任务。下面,让我们一起来看看shell是如何工作的:建立一个脚本Linux中有好多中不同的shell,但是通常我们使用bash (bourne again shell) 进行shell编程,因为bash是免费的并且很容易使用。所以在本文中笔者所提供的脚本都是使用bash(但是在大多数情况下,这些脚本同样可以在bash的大姐,bourne shell中运行)。如同其他语言一样,通过我们使用任意一种文字编辑器,比如nedit、kedit、emacs、vi等来编写我们的shell程序。

程序必须以下面的行开始(必须方在文件的第一行):#!/bin/sh符号#!用来告诉系统它后面的参数是用来执行该文件的程序。在这个例子中我们使用/bin/sh来执行程序。当编辑好脚本时,如果要执行该脚本,还必须使其可执行。

要使脚本可执行:chmod +x filename 然后,您可以通过输入: ./filename 来执行您的脚本。注释在进行shell编程时,以#开头的句子表示注释,直到这一行的结束。我们真诚地建议您在程序中使用注释。

如果您使用了注释,那么即使相当长的时间内没有使用该脚本,您也能在很短的时间内明白该脚本的作用及工作原理。变量在其他编程语言中您必须使用变量。在shell编程中,所有的变量都由字符串组成,并且您不需要对变量进行声明。

要赋值给一个变量,您可以这样写: 变量名=值取出变量值可以加一个美元符号($)在变量前面: #!/bin/sh#对变量赋值:a=”hello world”# 现在打印变量a的内容:echo “A is:”echo $a在您的编辑器中输入以上内容,然后将其保存为一个文件first。之后执行chmod +x first 使其可执行,最后输入./first执行该脚本。这个脚本将会输出:A is:hello world有时候变量名很容易与其他文字混淆,比如:num=2echo “this is the $numnd”这并不会打印出”this is the 2nd”,而仅仅打印”this is the “,因为shell会去搜索变量numnd的值,但是这个变量时没有值的。可以使用花括号来告诉shell我们要打印的是num变量: num=2echo “this is the ${num}nd”这将打印: this is the 2nd 有许多变量是系统自动设定的,这将在后面使用这些变量时进行讨论。

如果您需要处理数学表达式,那么您需要使用诸如expr等程序(见下面)。除了一般的仅在程序内有效的shell变量以外,还有环境变量。由export关键字处理过的变量叫做环境变量。我们不对环境变量进行讨论,因为通常情况下仅仅在登录脚本中使用环境变量。

Shell命令和流程控制在shell脚本中可以使用三类命令:1)Unix 命令:虽然在shell脚本中可以使用任意的unix命令,但是还是由一些相对更常用的命令。这些命令通常是用来进行文件和文字操作的。常用命令语法及功能echo “some text”: 将文字内容打印在屏幕上ls: 文件列表wc –l filewc -w filewc -c file: 计算文件行数计算文件中的单词数计算文件中的字符数cp sourcefile destfile: 文件拷贝mv oldname newname : 重命名文件或移动文件rm file: 删除文件grep ‘pattern’ file: 在文件内搜索字符串比如:grep ‘searchstring’ file.txtcut -b colnum file: 指定欲显示的文件内容范围,并将它们输出到标准输出设备比如:输出每行第5个到第9个字符cut -b5-9 file.txt千万不要和cat命令混淆,这是两个完全不同的命令cat file.txt: 输出文件内容到标准输出设备(屏幕)上file somefile: 得到文件类型read var: 提示用户输入,并将输入赋值给变量sort file.txt: 对file.txt文件中的行进行排序uniq: 删除文本文件中出现的行列比如: sort file.txt | uniqexpr: 进行数学运算Example: add 2 and 3expr 2 “+” 3find: 搜索文件比如:根据文件名搜索find . -name filename -printtee: 将数据输出到标准输出设备(屏幕) 和文件比如:somecommand | tee outfilebasename file: 返回不包含路径的文件名比如: basename /bin/tux将返回 tuxdirname file: 返回文件所在路径比如:dirname /bin/tux将返回 /binhead file: 打印文本文件开头几行tail file : 打印文本文件末尾几行sed: Sed是一个基本的查找替换程序。可以从标准输入(比如命令管道)读入文本,并将结果输出到标准输出(屏幕)。

该命令采用正则表达式(见参考)进行搜索。不要和shell中的通配符相混淆。比如:将linuxfocus 替换为 LinuxFocus :cat text.file | sed ‘s/linuxfocus/LinuxFocus/’ > newtext.fileawk: awk 用来从文本文件中提取字段。

缺省地,字段分割符是空格,可以使用-F指定其他分割符。cat file.txt | awk -F, ‘{print $1 “,” $3 }’这里我们使用,作为字段分割符,同时打印第一个和第三个字段。如果该文件内容如下: Adam Bor, 34, IndiaKerry Miller, 22, USA命令输出结果为:Adam Bor, IndiaKerry Miller, USA2) 概念: 管道, 重定向和 backtick这些不是系统命令,但是他们真的很重要。

管道 (|) 将一个命令的输出作为另外一个命令的输入。grep “hello” file.txt | wc -l在file.txt中搜索包含有”hello”的行并计算其行数。在这里grep命令的输出作为wc命令的输入。当然您可以使用多个命令。

重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。> 写入文件并覆盖旧文件>> 加到文件的尾部,保留旧文件内容。反短斜线使用反短斜线可以将一个命令的输出作为另外一个命令的一个命令行参数。

命令: find . -mtime -1 -type f -print用来查找过去24小时(-mtime –2则表示过去48小时)内修改过的文件。如果您想将所有查找到的文件打一个包,则可以使用以下脚本: #!/bin/sh# The ticks are backticks (`) not normal quotes (‘):tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`3) 流程控制”if” 表达式 如果条件为真则执行then后面的部分: if ….; then  ….elif ….; then  ….else  ….fi大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等…通常用” [ ] “来表示条件测试。注意这里的空格很重要。

要确保方括号的空格。 [ -f “somefile” ] :判断是否是一个文件[ -x “/bin/ls” ] :判断/bin/ls是否存在并有可执行权限[ -n “$var” ] :判断$var变量是否有值[ “$a” = “$b” ] :判断$a和$b是否相等执行man test可以查看所有测试表达式可以比较和判断的类型。直接执行以下脚本: #!/bin/shif [ “$SHELL” = “/bin/bash” ]; then  echo “your login shell is the bash (bourne again shell)”else  echo “your login shell is not bash but $SHELL”fi变量$SHELL包含了登录shell的名称,我们和/bin/bash进行了比较。

快捷操作符熟悉C语言的朋友可能会很喜欢下面的表达式:[ -f “/etc/shadow” ] && echo “This computer uses shadow passwors”这里 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句。您也可以认为是逻辑运算中的与操作。上例中表示如果/etc/shadow文件存在则打印” This computer uses shadow passwors”。同样或操作(||)在shell编程中也是可用的。这里有个例子: #!/bin/shmailfolder=/var/sp。

菜鸟入门问题:shell 与“终端”是什么?

图片[3]-LINUX快速入门第八章:Shell基础-学吧号

Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。

实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。

不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。Shell编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。   Linux提供了像Microsoft Windows那样的可视的命令输入界面(也就是你说的终端),Window是图形用户界面(GUI)。它提供了很多窗口管理器。

shell脚本编程

图片[4]-LINUX快速入门第八章:Shell基础-学吧号

tpu

关于如何学习shell脚本,该怎么写

图片[5]-LINUX快速入门第八章:Shell基础-学吧号

1. Linux 脚本编写基础1.1 语法基本介绍1.1.1 开头程序必须以下面的行开始(必须方在文件的第一行):#!/bin/sh符号#!用来告诉系统它后面的参数是用来执行该文件的程序。在这个例子中我们使用/bin/sh来执行程序。

当编辑好脚本时,如果要执行该脚本,还必须使其可执行。

要使脚本可执行:编译 chmod +x filename 这样才能用./filename 来运行1.1.2 注释在进行shell编程时,以#开头的句子表示注释,直到这一行的结束。我们真诚地建议您在程序中使用注释。如果您使用了注释,那么即使相当长的时间内没有使用该脚本,您也能在很短的时间内明白该脚本的作用及工作原理。1.1.3 变量在其他编程语言中您必须使用变量。

在shell编程中,所有的变量都由字符串组成,并且您不需要对变量进行声明。要赋值给一个变量,您可以这样写:#!/bin/sh#对变量赋值:a=”hello world”# 现在打印变量a的内容:echo “A is:”echo $a有时候变量名很容易与其他文字混淆,比如:num=2echo “this is the $numnd”这并不会打印出”this is the 2nd”,而仅仅打印”this is the “,因为shell会去搜索变量numnd的值,但是这个变量时没有值的。可以使用花括号来告诉shell我们要打印的是num变量:num=2echo “this is the ${num}nd”这将打印: this is the 2nd1.1.4 环境变量由export关键字处理过的变量叫做环境变量。

我们不对环境变量进行讨论,因为通常情况下仅仅在登录脚本中使用环境变量。1.1.5 Shell命令和流程控制在shell脚本中可以使用三类命令:1)Unix 命令:虽然在shell脚本中可以使用任意的unix命令,但是还是由一些相对更常用的命令。这些命令通常是用来进行文件和文字操作的。

常用命令语法及功能echo “some text”: 将文字内容打印在屏幕上ls: 文件列表wc –l filewc -w filewc -c file: 计算文件行数计算文件中的单词数计算文件中的字符数cp sourcefile destfile: 文件拷贝mv oldname newname : 重命名文件或移动文件rm file: 删除文件grep ‘pattern’ file: 在文件内搜索字符串比如:grep ‘searchstring’ file.txtcut -b colnum file: 指定欲显示的文件内容范围,并将它们输出到标准输出设备比如:输出每行第5个到第9个字符cut -b5-9 file.txt千万不要和cat命令混淆,这是两个完全不同的命令cat file.txt: 输出文件内容到标准输出设备(屏幕)上file somefile: 得到文件类型read var: 提示用户输入,并将输入赋值给变量sort file.txt: 对file.txt文件中的行进行排序uniq: 删除文本文件中出现的行列比如: sort file.txt | uniqexpr: 进行数学运算Example: add 2 and 3expr 2 “+” 3find: 搜索文件比如:根据文件名搜索find . -name filename -printtee: 将数据输出到标准输出设备(屏幕) 和文件比如:somecommand | tee outfilebasename file: 返回不包含路径的文件名比如: basename /bin/tux将返回 tuxdirname file: 返回文件所在路径比如:dirname /bin/tux将返回 /binhead file: 打印文本文件开头几行tail file : 打印文本文件末尾几行sed: Sed是一个基本的查找替换程序。可以从标准输入(比如命令管道)读入文本,并将结果输出到标准输出(屏幕)。该命令采用正则表达式(见参考)进行搜索。

不要和shell中的通配符相混淆。比如:将linuxfocus 替换为LinuxFocus :cat text.file | sed ‘s/linuxfocus/LinuxFocus/’ > newtext.fileawk: awk 用来从文本文件中提取字段。缺省地,字段分割符是空格,可以使用-F指定其他分割符。cat file.txt | awk -F, ‘{print $1 “,” $3 }’这里我们使用,作为字段分割符,同时打印第一个和第三个字段。

如果该文件内容如下: Adam Bor, 34, IndiaKerry Miller, 22, USA命令输出结果为:Adam Bor, IndiaKerry Miller, USA2) 概念: 管道, 重定向和 backtick这些不是系统命令,但是他们真的很重要。管道 (|) 将一个命令的输出作为另外一个命令的输入。grep “hello” file.txt | wc -l在file.txt中搜索包含有”hello”的行并计算其行数。在这里grep命令的输出作为wc命令的输入。

当然您可以使用多个命令。重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。> 写入文件并覆盖旧文件>> 加到文件的尾部,保留旧文件内容。反短斜线使用反短斜线可以将一个命令的输出作为另外一个命令的一个命令行参数。

命令:find . -mtime -1 -type f -print用来查找过去24小时(-mtime –2则表示过去48小时)内修改过的文件。如果您想将所有查找到的文件打一个包,则可以使用以下脚本:#!/bin/sh# The ticks are backticks (`) not normal quotes (‘):tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`3) 流程控制1.if”if” 表达式 如果条件为真则执行then后面的部分:if ….; then….elif ….; then….else….fi大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等…通常用” [ ] “来表示条件测试。

注意这里的空格很重要。要确保方括号的空格。[ -f “somefile” ] :判断是否是一个文件[ -x “/bin/ls” ] :判断/bin/ls是否存在并有可执行权限[ -n “$var” ] :判断$var变量是否有值[ “$a” = “$b” ] :判断$a和$b是否相等执行man test可以查看所有测试表达式可以比较和判断的类型。

直接执行以下脚本:#!/bin/shif [ “$SHELL” = “/bin/bash” ]; thenecho “your login shell is the bash (bourne again shell)”elseecho “your login shell is not bash but $SHELL”fi变量$SHELL包含了登录shell的名称,我们和/bin/bash进行了比较。快捷操作符熟悉C语言的朋友可能会很喜欢下面的表达式:[ -f “/etc/shadow” ] && echo “This computer uses shadow passwors”这里 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句。您也可以认为是逻辑运算中的与操作。上例中表示如果/etc/shadow文件存在则打印” This computer uses shadow passwors”。

同样或操作(||)在shell编程中也是可用的。这里有个例子:#!/bin/shmailfolder=/var/spool/mail/james[ -r “$mailfolder” ]’ ‘{ echo “Can not read $mailfolder” ; exit 1; }echo “$mailfolder has mail from:”grep “^From ” $mailfolder该脚本首先判断mailfolder是否可读。如果可读则打印该文件中的”From” 一行。

如果不可读则或操作生效,打印错误信息后脚本退出。这里有个问题,那就是我们必须有两个命令:-打印错误信息-退出程序我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用。一般函数将在下文提及。不用与和或操作符,我们也可以用if表达式作任何事情,但是使用与或操作符会更便利很多。

2.casecase :表达式可以用来匹配一个给定的字符串,而不是数字。case … in…) do something here ;;esac让我们看一个例子。 file命令可以辨别出一个给定文件的文件类型,比如:file lf.gz这将返回:lf.gz: gzip compressed data, deflated, original filename,last modified: Mon Aug 27 23:09:18 2001, os: Unix我们利用这一点写了一个叫做smartzip的脚本,该脚本可以自动解压bzip2, gzip 和zip 类型的压缩文件:#!/bin/shftype=`file “$1″`case “$ftype” in”$1: Zip archive”*)unzip “$1” ;;”$1: gzip compressed”*)gunzip “$1” ;;”$1: bzip2 compressed”*)bunzip2 “$1” ;;*) echo “File $1 can not be uncompressed with smartzip”;;esac您可能注意到我们在这里使用了一个特殊的变量$1。

该变量包含了传递给该程序的第一个参数值。也就是说,当我们运行:smartzip articles.zip$1 。

怎么学习shell

图片[6]-LINUX快速入门第八章:Shell基础-学吧号

写作思路
为了能快速上手 Shell 语法,在很多时候我会对一些不是很重要的内容进行舍弃。这些内容则会作为补充内容在后续的文章中说明。

例如在 Shell 中有许多种循环结构:for 循环、while 循环、util 循环,但实际上 while 循环和 until 循环基本上是一样的。

在这种情况下我舍弃对于 until 循环这个语法的介绍。
例如在 Shell 中进行数学运算有很多种方式,可以使用-eq操作符,可以使用==操作符,可以使用=操作符、可以使用(())操作符等等。这个时候我也会进行取舍,取一种最简单、最通用的语法来实现。舍弃一些复杂的语法并不会影响我们使用 Shell 语言,反而会让我们更快入手。

这是本系列跟其他 Shell 入门教程的最大不同,即以快速入手为目的,并不追求大而全。对于入门系列的文章,目前写了大概十四篇。每篇文章阅读不会超过 10 分钟,每个知识点都有相应的代码可以运行,确保小白都能看得懂。

THE END
喜欢就支持一下吧
点赞10
温馨提示:

1、本内容转载于网络,版权归原作者所有!
2、本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
3、本内容若侵犯到你的版权利益,请联系我QQ:243371741,会尽快给予删除处理!