$@ 与 $* 差在哪?-- Shell十三问<第九问>

要说 $@ 与 $* 之前,需得先从 shell script 的 positional parameter 谈起.我们都已经知道变量(variable)是如何定义及替换的,这个不用再多讲了。

但是,我们还需要知道有些变量是 shell 内定的,且其名称是我们不能随意修改的,其中就有 positional parameter 在内。

在 shell script 中,我们可用 $0, $1, $2, $3 ... 这样的变量分别提取命令行中的如下部份:

script_name parameter1 parameter2 parameter3 .

我们很容易就能猜出 $0 就是代表 shell script 名称(路径)本身,而 $1 就是其后的第一个参数,如此类推.须得留意的是 IFS 的作用,也就是,若 IFS 被 quoting 处理后,那么 positional parameter 也会改变。

如下例:

my.sh p1 "p2 p3" p4

由于在 p2 与 p3 之间的空格键被 soft quote 所关闭了,因此 my.sh 中的 $2 是 "p2 p3",而 $3 则是 p4.

还记得前两章我们提到 fucntion 时,我不是说过它是 script 中的 script 吗?

是的,function 一样可以读取自己的(有别于 script 的) postitional parameter ,惟一例外的是 $0 而已。

举例而言:假设 my.sh 里有一个 fucntion 叫 my_fun , 若在 script 中跑 my_fun fp1 fp2 fp3,那么,function 内的 $0 是 my.sh ,而 $1 则是 fp1 而非 p1 了.

不如写个简单的 my.sh script 看看吧:

#!/bin/bash
my_fun() {
echo '$0 inside function is '$0
echo '$1 inside function is '$1
echo '$2 inside function is '$2
}
echo '$0 outside function is '$0
echo '$1 outside function is '$1
echo '$2 outside function is '$2
my_fun fp1 "fp2 fp3" 然后在 command line 中跑一下 script 就知道了:
chmod +x my.sh
./my.sh p1 "p2 p3"
$0 outside function is ./my.sh
$1 outside function is p1
$2 outside function is p2 p3
$0 inside function is ./my.sh
$1 inside function is fp1
$2 inside function is fp2 fp3

使用 positional parameter 的时候,我们要注意一些陷阱哦:

  • $10 不是替换第 10 个参数,而是替换第一个参数($1)然后再补一个 0 于其后!

    也就是,my.sh one two three four five six seven eigth nine ten 这样的 command line ,my.sh 里的 $10 不是 ten 而是 one0 哦.

要抓到 ten 的话,有两种方法:

  1. 方法一,是使用我们上一章介绍的 ${ } ,也就是用 ${10} 即可。
  2. 方法二,就是 shift 了。

用通俗的说法来说,所谓的 shift 就是取消 positional parameter 中最左边的参数( $0 不受影响)。其默认值为 1 ,也就是 shift 或 shift 1 都是取消 $1 ,而原本的 $2 则变成 $1、$3 变成 $2. 若 shift 3 则是取消前面三个参数,也就是原本的 $4 将变成 $1.

那,亲爱的读者,你说要 shift 掉多少个参数,才可用 $1 取得 ${10} 呢? 当我们对 positional parameter 有了基本概念之后,那再让我们看看其它相关变量吧。

首先是 $# :它可抓出 positional parameter 的数量。以前面的 my.sh p1 "p2 p3" 为例:

由于 p2 与 p3 之间的 IFS 是在 soft quote 中,因此 $# 可得到 2 的值。但如果 p2 与 p3 没有置于 quoting 中话,那 $# 就可得到 3 的值了。

同样的道理在 function 中也是一样的.

因此,我们常在 shell script 里用如下方法测试 script 是否有读进参数:

[ $# = 0 ]
假如为 0 ,那就表示 script 没有参数,否则就是有带参数...
接下来就是 $@ 与 $* :
精确来讲,两者只有在 soft quote 中才有差异,否则,都表示"全部参数"( $0 除外)。
举例来说好了:
若在 command line 上跑 my.sh p1 "p2 p3" p4 的话,
不管是 $@ 还是 $* ,都可得到 p1 p2 p3 p4 就是了。
但是,如果置于 soft quote 中的话:
"$@" 则可得到 "p1" "p2 p3" "p4" 这三个不同的词段(word)﹔
"$*" 则可得到 "p1 p2 p3 p4" 这一整串单一的词段。

我们可修改一下前面的 my.sh ,使之内容如下:

#!/bin/bash
my_fun() {
echo "$#"
}
echo 'the number of parameter in "$@" is '$(my_fun "$@")
echo 'the number of parameter in "$*" is '$(my_fun "$*")
然后再执行 ./my.sh p1 "p2 p3" p4 就知道 $@ 与 $* 差在哪了 .

$@ 与 $* 差在哪?-- Shell十三问<第九问>的更多相关文章

  1. > 与 < 差在哪?-- Shell十三问<第十一问>

    > 与 < 差在哪?-- Shell十三问<第十一问> 谈到 I/O redirection ,不妨先让我们认识一下 File Descriptor (FD) .程序的运算,在 ...

  2. && 与 || 差在哪?-- Shell十三问<第十问>

    && 与 || 差在哪?-- Shell十三问<第十问> 好不容易,进入两位数的章节了... 一路走来,很辛苦吧?也很快乐吧? 在解答本章题目之前,先让我们了解一个概念:r ...

  3. $(( )) 与 $( ) 还有${ } 差在哪?-- Shell十三问<第八问>

    $(( )) 与 \(( ) 还有\){ } 差在哪?-- Shell十三问<第八问> 我们上一章介绍了 ( ) 与 { } 的不同,这次让我们扩展一下,看看更多的变化:$( ) 与 \( ...

  4. ( ) 与 { } 差在哪?-- Shell十三问<第七问>

    ( ) 与 { } 差在哪?-- Shell十三问<第七问> 先说一下,为何要用 ( ) 或 { } 好了. 许多时候,我们在 shell 操作上,需要在一定条件下一次执行多个命令,也就是 ...

  5. exec 跟 source 差在哪?-- Shell十三问<第六问>

    exec 跟 source 差在哪?-- Shell十三问<第六问> 这次先让我们从 CU Shell 版的一个实例贴子来谈起吧: 例中的提问是: cd /etc/aa/bb/cc 可以执 ...

  6. var=value?export前后差在哪?-- Shell十三问<第五问>

    var=value?export前后差在哪?-- Shell十三问<第五问> 这次让我们暂时丢开 command line ,先来了解一下 bash 变量(variable)吧.所谓的 变 ...

  7. " "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问>

    " "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问> 经过前面两章的学习,应该很清楚当你在 shell prompt 后面敲打键盘.直到 ...

  8. 别人 echo 、你也 echo ,是问 echo 知多少?-- Shell十三问<第三问>

    别人 echo .你也 echo ,是问 echo 知多少?-- Shell十三问<第三问> 承接上一章所介绍的 command line ,这里我们用 echo 这个命令加以进一步说明. ...

  9. [^ ] 跟 [! ] 差在哪?-- Shell十三问<第十四问>

    [^ ] 跟 [! ] 差在哪?-- Shell十三问<第十四问> 这道题目说穿了, 就是要探讨 Wildcard(通配符)与 Regular Expression(正则表达式)的差别的. ...

  10. shell十三问

    1) 为何叫做 shell ?在介绍 shell 是甚幺东西之前,不妨让我们重新检视使用者与计算机系统的关系:图(FIXME)我们知道计算机的运作不能离开硬件,但使用者却无法直接对硬件作驱动,硬件的驱 ...

随机推荐

  1. onsen & UI & vue & mobile UI

    onsen & UI vue & mobile UI $ npm i onsenui vue-onsenui # OR $ npm i -S onsenui vue-onsenui h ...

  2. eclipse自定义快捷键

    eclipse系统自带的快捷键设置有时候使用起来并不习惯,可以自定义某些常用的快捷键. 依次打开 Window->Preference->General->Keys,这里显示了所有的 ...

  3. hive复杂数据类型的用法

    目录 1.简单描述 2.测试 1.简单描述 arrays: ARRAY<data_type> maps: MAP<primitive_type, data_type> stru ...

  4. 分分钟钟学会Python - 第四章 文件操作

    4.1 文件基本操作 obj = open('路径',mode='模式',encoding='编码') obj.write() # 写入 obj.read() # 读取 obj.close() #关闭 ...

  5. 看完我的笔记不懂也会懂----MongoDB

    MongoDb数据库学习 - 数据库的分类 - 数据库基本概念 - MongoDB常用指令 - MongoDB的CURD - sort({key:*[1,-1]}).limit(num).skip(n ...

  6. 力扣119. 杨辉三角 II

    原题 1 class Solution: 2 def getRow(self, rowIndex: int) -> List[int]: 3 ans = [1] 4 for i in range ...

  7. Java垃圾回收机制详解

    前言 Java 相比 C/C++ 最显著的特点便是引入了自动垃圾回收 (下文统一用 GC 指代自动垃圾回收),它解决了 C/C++ 最令人头疼的内存管理问题,让程序员专注于程序本身,不用关心内存回收这 ...

  8. C语言中字符串详解

    C语言中字符串详解 字符串时是C语言中非常重要的部分,我们从字符串的性质和字符串的创建.程序中字符串的输入输出和字符串的操作来对字符串进行详细的解析. 什么是字符串? C语言本身没有内置的字符串类型, ...

  9. python3+tkinter实现的黑白棋,代码完整 100%能运行

    今天分享给大家的是采用Python3+tkinter制作而成的小项目--黑白棋 tkinter是Python内置的图形化模块,简单易用,一般的小型UI程序可以快速用它实现,具体的tkinter相关知识 ...

  10. 关于PHP的表单数组提交显示

    1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <meta chars ...