Shell基本编程04

夕阳无限好,只是近黄昏。——李商隐《乐游原》

终于到第四趴了,这也将是这个系列的最后一个部分了。我先把结束语写在前面吧,Shell是一门博大精深的脚本语言,实际上因为Shell可以直接调用很多现成的或者定制的命令,比如awk,比如top,甚至java 命令行,这就在事实上给了shell可扩展的无限可能性。所以到目前为止带大家所看到的只是shell编程冰山的一角,希望大家在日常使用中慢慢积累。有机会的话我们再谈一谈OOTB的linux命令集。find, sed, grep, 等等,又将是一个很大的话题。

04

Shell函数

函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。Shell 函数必须先定义后使用。

[function] function_name () { list of commands [ return value ]}

function 关键字为可选。可以用显式return语句提供返回值;如果不加,会将最后一条命令运行结果作为返回值。

Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果 return 其他数据,比如一个字符串,往往会得到错误提示:“numeric argument required”。

如果一定要让函数返回字符串,权宜之计是先定义一个变量,用来存放函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。这更像是oracle 存储过程中的 out参数。

函数的调用不需要加括号。

来看个例子:

#!/bin/bash

funWithReturn(){

echo"The function is to get the sum of two numbers..."

echo-n"Input first number: "

readaNum

echo-n"Input another number: "

readanotherNum

echo"The two numbers are $aNum and $anotherNum !"

return$(($aNum+$anotherNum))

}

funWithReturn

# Capture value returnd by last command

ret=$?

echo"The sum of two numbers is $ret !"

运行结果:

The function is to get the sum of two numbers...Input first number: 25Input another number: 50The two numbers are 25 and 50 !The sum of two numbers is 75 !

像删除变量一样,删除函数也可以使用 unset 命令,不过要加上 .f 选项,如下所示:

$unset.f function_name

和执行脚本类似,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数... 另外,$#, $@, $*的作用也和前文诉述的作用一致。

#!/bin/bash

funWithParam(){

echo"The value of the second parameter is $2 !"

echo"The amount of the parameters is $# !"# 参数个数

echo"The string of the parameters is $* !"# 传递给函数的所有参数

}

funWithParam123

输出如下:

The value of the second parameter is 2 !The amount of the parameters is 3!The string of the parameters is 1 2 3!"

注意,$10 不能获取第十个参数,获取第十个参数需要$。当n>=10时,需要使用$来获取参数。

Shell输入输出重定向

命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向。语法为

$command>file

输出重定向会覆盖文件内容,如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,例如:

$ echo line 2 >> file

和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:

$command

这样,本来需要从键盘获取输入的命令会转移到文件读取内容。l例如,

$ wc -l

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。

标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。

标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

如果希望 stderr 重定向到 file,可以这样写:

$command2>file

2 表示标准错误文件(stderr)。

如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

$command>file2>&1

$command>>file2>&1

如果希望对 stdin 和 stdout 分别重定向,可以这样写:

$commandfile2

Here Document

Document 是 Shell 中的一种特殊的重定向方式,它的基本的形式如下:

command

document content

delimiter

它的作用是将两个 delimiter 之间的内容作为输入传递给 command。

注意:

结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。

开始的delimiter前后的空格会被忽略掉。

下面的例子,通过 wc -l 命令计算 document 的行数:

$wc -l

下面的脚本通过 vi 编辑器将 document 保存到 test.txt 文件:

#!/bin/sh

filename=test.txt

vi$filename

This file was created automatically from

a shell script

^[

ZZ

EndOfCommands

运行脚本:

$ sh test.shVim: Warning: Input is not from a terminal$

打开 test.txt,可以看到下面的内容:

$ cat test.txtThis file was created automatically froma shell script$

/dev/null 文件

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。如果希望屏蔽 stdout 和 stderr,可以这样写:

$command>/dev/null2>&1

Shell文件包含

Shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本。Shell 中包含脚本可以使用:

.filename

sourcefilename

注意,点号(.)和文件名中间有一空格。

例如,创建两个脚本,一个是被调用脚本 subscript.sh,内容如下:

name="glen"

一个是主文件 main.sh,内容如下:

#!/bin/bash

../subscript.sh

echo$name

执行脚本:

$chomd +x main.sh./main.shglen$

注意,被包含脚本不需要有执行权限。

Shell调试

shell调试有三种方式

命令行方式

sh -x shell.script

脚本文件首行指定

#!/bin/bash -x

使用set

set -x

-v 显示所有行,详细模式

-n 检查语法,不执行命令

-x shell 跟踪模式,显示所有命令和参数

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180621G21AVI00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券