$@ 与 $* 差在哪?-- Shell十三问<第九问>
$@ 与 $* 差在哪?-- 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 的话,有两种方法:
- 方法一,是使用我们上一章介绍的 ${ } ,也就是用 ${10} 即可。
- 方法二,就是 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十三问<第九问>的更多相关文章
- > 与 < 差在哪?-- Shell十三问<第十一问>
> 与 < 差在哪?-- Shell十三问<第十一问> 谈到 I/O redirection ,不妨先让我们认识一下 File Descriptor (FD) .程序的运算,在 ...
- && 与 || 差在哪?-- Shell十三问<第十问>
&& 与 || 差在哪?-- Shell十三问<第十问> 好不容易,进入两位数的章节了... 一路走来,很辛苦吧?也很快乐吧? 在解答本章题目之前,先让我们了解一个概念:r ...
- $(( )) 与 $( ) 还有${ } 差在哪?-- Shell十三问<第八问>
$(( )) 与 \(( ) 还有\){ } 差在哪?-- Shell十三问<第八问> 我们上一章介绍了 ( ) 与 { } 的不同,这次让我们扩展一下,看看更多的变化:$( ) 与 \( ...
- ( ) 与 { } 差在哪?-- Shell十三问<第七问>
( ) 与 { } 差在哪?-- Shell十三问<第七问> 先说一下,为何要用 ( ) 或 { } 好了. 许多时候,我们在 shell 操作上,需要在一定条件下一次执行多个命令,也就是 ...
- exec 跟 source 差在哪?-- Shell十三问<第六问>
exec 跟 source 差在哪?-- Shell十三问<第六问> 这次先让我们从 CU Shell 版的一个实例贴子来谈起吧: 例中的提问是: cd /etc/aa/bb/cc 可以执 ...
- var=value?export前后差在哪?-- Shell十三问<第五问>
var=value?export前后差在哪?-- Shell十三问<第五问> 这次让我们暂时丢开 command line ,先来了解一下 bash 变量(variable)吧.所谓的 变 ...
- " "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问>
" "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问> 经过前面两章的学习,应该很清楚当你在 shell prompt 后面敲打键盘.直到 ...
- 别人 echo 、你也 echo ,是问 echo 知多少?-- Shell十三问<第三问>
别人 echo .你也 echo ,是问 echo 知多少?-- Shell十三问<第三问> 承接上一章所介绍的 command line ,这里我们用 echo 这个命令加以进一步说明. ...
- [^ ] 跟 [! ] 差在哪?-- Shell十三问<第十四问>
[^ ] 跟 [! ] 差在哪?-- Shell十三问<第十四问> 这道题目说穿了, 就是要探讨 Wildcard(通配符)与 Regular Expression(正则表达式)的差别的. ...
- shell十三问
1) 为何叫做 shell ?在介绍 shell 是甚幺东西之前,不妨让我们重新检视使用者与计算机系统的关系:图(FIXME)我们知道计算机的运作不能离开硬件,但使用者却无法直接对硬件作驱动,硬件的驱 ...
随机推荐
- Scalability & Scale-up & Scale-out
Scalability & Scale-up & Scale-out 架构,弹性,伸缩性 Scalability 可扩展性 https://en.wikipedia.org/wiki/ ...
- 黑马来袭!NGK生态所二月上线!
日前,加密货币交易所Coinbase Global Inc,向美国证券交易委员会申请首次公开募股,成为首家公开上市的加密货币交易所."Coinbase上市,给行业带来更多的是信心.让大家看到 ...
- 倒计时2天!2021 NGK新加坡区块链峰会与你不见不散!
1月31日14时,NGK将于新加坡召开"2021 NGK新加坡区块链峰会",并将在全球开启同步直播. 据了解,本次峰会将汇聚全球二十多位顶尖区块链专家学者,与NGK灵石技术团队 ...
- golang官方嵌入文件到可执行程序
目录 前言 示例程序 嵌入文件直接访问 嵌入文件列表 总结 前言 在go官方出嵌入文件的方法前我在网上找过,并且自己还研究过,虽然没有问题,但是既然官方支持还是用起来吧. 看了下go源码embed/e ...
- int和Integer的比较详解
说明: int为基本类型,Integer为包装类型: 装箱: 基本类型---> 包装类型 int ---> Integer 底层源码: .intValue() 拆箱: 包装类型---> ...
- RTPS解析
资料参考: https://blog.csdn.net/HBS2011/article/details/102520704
- 使用docker mediawiki,搭建网页wiki
我只是想做一个大家都能访问的wiki,用于成员间共享和维护一些文档.找到了docker的mediawiki,这里记录一下我怎么搭的吧. 首先,如果你在一个局域网里,有公用的可以访问的服务器,那可以直接 ...
- 基于3.X版本的脚手架创建VUE项目
一.基于交互式命令行的方式,创建vue项目 1.命令:vue create 项目名称.项目名称必须是英文的.不要包含中文.特殊的字符和符号.在cmd中输入命令:vue create vue_proje ...
- 单细胞分析实录(9): 展示marker基因的4种图形(二)
在上一篇中,我已经讲解了展示marker基因的前两种图形,分别是tsne/umap图.热图,感兴趣的读者可以回顾一下.这一节我们继续学习堆叠小提琴图和气泡图. 3. 堆叠小提琴图展示marker基因 ...
- #progma pack(x)说明
1.字节对齐(内存相关) 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数 ...