$@ 与 $* 差在哪?-- 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. Python3 & Decorators with arguments & @Decorators with arguments bug

    Python3 & Decorators with arguments & @Decorators with arguments bug @Decorators with argume ...

  2. live chat for website UX

    live chat for website UX increase customer satisfaction using a live chat https://crisp.chat/en/live ...

  3. Github Trending All In One

    Github Trending All In One github trending https://github.com/trending https://github.com/trending/j ...

  4. IndexedDB All In One

    IndexedDB All In One https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API https://develope ...

  5. Flutter: 粘贴板

    文档 import 'package:flutter/services.dart'; /// 把文本复制进入粘贴板 Clipboard.setData(ClipboardData(text: &quo ...

  6. 倒计时2天!2021 NGK新加坡区块链峰会与你不见不散!

    1月31日14时,NGK将于新加坡召开"2021 NGK新加坡区块链峰会",并将在全球开启同步直播.   据了解,本次峰会将汇聚全球二十多位顶尖区块链专家学者,与NGK灵石技术团队 ...

  7. NGK数字增益平台中如何分配代币产出

    最近很多朋友听说NGK公链的主网和数字增益平台即将上线以后都纷纷表示非常感兴趣,已经基本了解了NGK代币的产出方式,但还是对代币产出分配的问题不是很明确.今天小编就给大家科普一下,NGK代币在NGK数 ...

  8. Masterboxan INC:OPEC+达成产量协议 产油联盟内部分歧逐步加大

    本周,"OPEC+"在维也纳召开了今年首次部长级会议,并就未来两个月的石油生产计划达成协议.据了解,此次会议的协商过程可谓一波三折,虽然最后沙特意外宣布减产维持了OPEC+大体产量 ...

  9. 用Python实现一个“百度翻译”

    import requests import json s = input("请输入你要翻译的内容:") headers = {"User-Agent":&qu ...

  10. Python数据结构与算法_反转字符串(08)

    编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 char[] 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这一问题. 你可以 ...