本文也即《Learning the bash Shell》3rd Edition的第四章Basic Shell Programming之读书笔记,但我们将不限于此。

运行shell脚本程序

  一个包含shell命令的脚本就是一个shell程序,例如.bash_profile。我们创建shell脚本,允许的时候可以通过两种方式:一、source ;二、只敲入文件名,按回车就可以执行,这种方式更为便捷。我们需要将文件放置在命令搜索路径下(在Linux Bash学习(六):设置环境参数 中介绍),否则需要指出绝对路径,例如在当前目录,使用./, 另外我们还需要将文件的权限设置为可执行文件,采用$ chmod +x 的方式设置,+x表示增加执行的权限。

  这两种方式是由区别的。采用source就如同我们在terminal上敲入命令一样。采用后一种方式,系统运行一个子进程,它copy了shell,叫作subshell,主shell等待子shell运行结束。另外我们设置让子shell后台运行,即 &

  这个区别还体现在export 的使用上,例如我们设置aa=hello, world,这个变量在命令行中有效,但是在脚本文件是无效,需要使用export aa='hello, world ' 来保证在subprocess中也是有效,即可以用于脚本文件中。

函数Functions

  使用function有两个原因:一、function存放在系统的内存,所以调用的使用,效率更高;二、更好地组织长的bash,使之模块化。定义function,有两个方式:

function functname {

shell commands

}

functname

( ){

shell commands

}

  上面两种方式没有区别。我们可以通过unset –f functname

来删除函数的定义。 当我们定义一个function,将它的名字和定义存放在内存,我们可以象调用shell脚本的方式来调用它。我们通过declare -f

来查看当前已经定义的function情况,如果我们只查看function名字,使用declare -F

。我们可以在命令行中敲入一个function来检验,如果我们将function定义在一个文件中,例如在文件a,可以用source a

来是指生效,如果我们将a设定为可执行文件,这function的定义只在该脚本中有效,如果需要使之仍然有效,保留环境,采用$.

./a

,而不只是$./a

Function作为一个整体运行,不会分割为子进程,此外Function的优先级别高于脚本。如果有重名,优先级别依次如下:

  1. Aliases
  2. 关键字,例如function,if,for
  3. Functions
  4. Built-ins,例如cd,type
  5. 在命令搜索路径PATH下的脚本和可执行文件

  如果我们需要查看所使用命令属于哪种,用type name

,例如aa是个alias(表示pwd),同样我们也定义了它作为一个function,根据优先级别,aa优先作为alias,type aa,我们可以得到aa is aliased to ‘pwd’,可以用type –a(或者-all) name

,来查看aa代表的所有含义。如果使用非最优先级别或者重新定义优先级别的先后顺序,在书的第7章,我们先放下此话题不表。上述的命令将显示详细内容,可以用type –t name

的方式,查看类型,将返回alias | keyword | function | builtin | file。type –p name

用于查看file的路径,如果类型不是file将没有返回,而type –P name

则强制查找file的路径。例如一个重名,它是一个alias,也是一个在PATH目录下的可执行文件。-p则没有返回,-P这返回文件的绝对路径。

位置参数

  在脚本命令中,有时是带有参数,这些参数可以通过位置变量来获取。例如我们有个脚本文件叫做test,执行的使用带参数,即$./test
param1 param2
param3,我们可以在脚本中来获取参数的值。使用$N,其中$0是./test,它表示执行的脚本名字,剩余的为所带参数,$1为param1,$2
为param2,如此类推,如果N大于实际参数的数目,为空。我们一般将位置变量是从$1开始。

$*

表示所有参数组成的一个字符串,在上面的例子中,为param1 param2 param3。这些参数之间的间隔是IFS的首个字母即空格,IFS包括TAB,空格,换行等字符。

$@

等同于"$1" "$2"... "$N"。

$#

表示参数的个数,在上面的例子中为3。

  这些位置变量都是只读,不能赋值的。$*和$@非常相似,一般而言输出是一样的。$*的分割是在IFS的字符,我们可以重新定义IFS的字符,将导致不同的输出结果。我们在脚本中定义IFS=,

,即可将输出改用逗号做为分割,这个脚本名字为a,运行./a h1 h2,则$#=2,表示有两个参数,$@为h1 h2,$*为h1,h2

,输出结果不一样。

  同样这些位置变量可以用于function中,并对function的参数进行体现,即是local的,属于function,但是$0是例外,他表示脚本的名字,这个参数是gobal的。下面是个例子。脚本a内容如下:

hello ()

{

var="hello";

echo "Hello"

echo "Hello: param num is $#"

echo "Hello: $@"

echo "Hello: $*"

echo "Hello: $0 $1 $2"

echo "Hello: var=$var";

}

var="hello";

echo "main: param num is $#"

echo "main: $@"

echo "main: $*"

echo "main: $0 $1 $2"

echo "main: var=$var";

hello h1 h2

  我们执行./a a1 a2 a3

main: param num is 3

main: a1 a2 a3

main: a1 a2 a3

main: ./a a1 a2

main: var=main

Hello

Hello: param num is 2

Hello: h1 h2

Hello: h1 h2

Hello: ./a h1 h2

Hello: var=hello

  除了$0外,所有的位置变量都是local的,即如果在function中,则在function中有效。同样,用户定义的其他变量,也是
local的,即在最近的{}内有效。见上面例子中的用户变量var。我们可以在function中定义var加上local来特别标明这是一个本地参
数,上面的例子在函数hello,可以使用local var=”hello”

避免歧义的变量定义

  实际上我们使用$varname,是${varname}

的一个缩写。有时我们不能使用缩写,例如我们需要获取第10个参数,使用$10,这实际是第一个参数加上“0”,需要使用${10}。又例如,我们希望显
示进程号,并在后面仅跟_、字母或者数字,我们使用echo $UID_,会见UID_看作一个整体,即echo
${UID_},因此是空,需要使用echo
${UID}_,假设进程号为1000,则为1000_。如果一个变量后面紧跟着_、字母或者数字,安全起见,需要用大括号。

Shell 函数 function [转]的更多相关文章

  1. Shell入门教程:Shell函数详解

    Shell函数类似于Shell脚本,里面存放了一系列的指令,不过Shell的函数存在于内存,而不是硬盘文件,所以速度很快,另外,Shell还能对函数进行预处理,所以函数的启动比脚本更快. 1.函数定义 ...

  2. Shell入门教程:Shell函数的返回值

    shell函数返回值一般有3种方式: 1.return语句(默认的返回值) shell函数的返回值可以和其他语言的返回值一样,通过return语句返回. 比如: #!/bin/bash functio ...

  3. (转)Shell函数

    Shell函数类似于Shell脚本,里面存放了一系列的指令,不过Shell的函数存在于内存,而不是硬盘文件,所以速度很快,另外,Shell还能对函数进行预处理,所以函数的启动比脚本更快. 1.  函数 ...

  4. Linux Shell系列教程之(十五) Shell函数简介

    本文是Linux Shell系列教程的第(十五)篇,更多Linux Shell教程请看:Linux Shell系列教程 函数可以将一个复杂功能划分成若干模块,从而使程序结构更加清晰,代码重复利用率更高 ...

  5. Shell函数语法

    Shell函数语法 定义函数: function   函数名(){ 指令... } 调用函数,方法1: 函数名 调用函数,方法2: 函数名  参数一   参数二 return在函数里面使用会跳出函数并 ...

  6. shell 函数

    1 shell函数的定义及其调用 shell函数有两种格式: function name { commands } name() { commands } 其中,name为函数名,commands为函 ...

  7. Shell函数:Shell函数返回值、删除函数、在终端调用函数

    函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高.像其他编程语言一样,Shell 也支持函数.Shell 函数必须先定义后使用. Shell 函数的定义格式如下: f ...

  8. Javascript学习之函数(function)

    在JS中,Function(函数)类型实际上是对象;每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针. 一 函 ...

  9. Shell函数返回值、删除函数、在终端调用函数

    Shell 也支持函数.Shell 函数必须先定义后使用. Shell 函数的定义格式如下: function_name () { list of commands [ return value ] ...

随机推荐

  1. ubuntu下sh文件使用

    可把shell命令批处理写进filename.sh文件 然后执行 chmod +x filename.sh 就可以执行./filename.sh了

  2. C语言指针总结

    C语言中的精华是什么,答曰指针,这也是C语言中唯一的难点. C是对底层操作非常方便的语言,而底层操作中用到最多的就是指针,以后从事嵌入式开发的朋友们,指针将陪伴我们终身. 本文将从八个常见的方面来透视 ...

  3. Android 相机对焦模式

    Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE  Camer ...

  4. php扩展开发初探

    2015年2月26日 15:44:41 原因: 想用PHP实现一个布隆过滤器算法, 其中要用到位运算, 但是PHP的内置的int类型不给力, 不能支持大整数的位运算 数据一旦太大, 就会变为浮点数表示 ...

  5. mybatis整合spring 之 基于接口映射的多对一关系

    转载自:http://my.oschina.net/huangcongmin12/blog/83731 mybatis整合spring 之  基于接口映射的多对一关系. 项目用到俩个表,即studen ...

  6. 【python】choice函数

    来源:http://www.runoob.com/python/func-number-choice.html 描述 choice() 方法返回一个列表,元组或字符串的随机项. 语法 以下是 choi ...

  7. UVA 11827 Maximum GCD (输入流)

    题目:传送门 题意:求n个数的最大公约数,暴力不会超时,难点在没有个数控制的输入. 题解:用特殊方法输入. #include <iostream> #include <cmath&g ...

  8. fopen()及相关函数使用

    函数简介 函数功能:打开一个文件 函数原型:FILE * fopen(const char * path,const char * mode); ],_wfopen 所需库:<stdio.h&g ...

  9. C# WPF 之 遍历子控件

    /// <summary> /// 检查非空字段 /// </summary> /// <param name="IsOk"></para ...

  10. javascript中window.open()与window.location.href的区别

    window.open("www.baidu.com"); 只是表示打开这个页面,并不是打开并刷新baidu.com window.location.href="www. ...