免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 8467 | 回复: 38
打印 上一主题 下一主题

$@和$*的问题!!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-02-21 21:44 |只看该作者 |倒序浏览
在看过shell13问以后,自己试验了一下,现有如下的问题,不知哪位高手能给于解答



  1. set -- "First Arg" "Second" "Third:Arg" "" "Fifth: :Arg"

  2. IFS=:

  3. var=$*
  4. var1=$@

  5. echo "$var"                        # First Arg:Second:Third:Arg::Fifth: :Arg
  6. echo "$var1"                      # First Arg Second Third Arg  Fifth   Arg

复制代码


为什么$var1变量会是这样的?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2006-02-22 02:37 |只看该作者
恩?
看起來是對對 IFS 的解釋不同?

這個我沒仔細去比較過呢.

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
3 [报告]
发表于 2006-02-22 08:38 |只看该作者
有什么不对么?
可能楼主认为$@解析的不对
可以在最后 echo "$@" 对比一下

var1=$@
首先bash将$@进行参数扩展( Parameter Expansion) 变为
First Arg Second Third:Arg  Fifth: :Arg
然后是单词分割( Word Splitting) IFS就在这时起作用,变为
First Arg Second Third Arg  Fifth   Arg


这里有个重要的概念
bash读入一行命令会首先以metacharacter对命令进行拆分成为一个个token
进行一系列的扩展,扩展的最后一道工序是以IFS进行Word Splitting
注意不要把两次拆分混淆了
bash的manpage中解释的很清楚,有空可以读一下

论坛徽章:
0
4 [报告]
发表于 2006-02-22 14:05 |只看该作者
原帖由 waker 于 2006-2-22 08:38 发表
有什么不对么?
可能楼主认为$@解析的不对
可以在最后 echo "$@" 对比一下

var1=$@
首先bash将$@进行参数扩展( Parameter Expansion) 变为
First Arg Second Third:Arg  Fifth: :Arg
然 ...


感谢waker,其实我在提问之前读过了manual和一些文档,如果按照waker兄的解释,那么下面的实例将解释不通.


  1. set -- "First Arg" "Second" "Third:Arg" "" "Fifth: :Arg"

  2. IFS=:

  3. for i in $@
  4. do
  5.   echo $i
  6. done

  7. ########
  8. First Arg
  9. Second
  10. Third
  11. Arg
  12. []       # 空
  13. Fifth
  14. [ ]      # 空格
  15. Arg

复制代码


所以我个人认为,$@和$*都会用IFS分隔每个元素,而不同之处在于$@会用缺省的IFS(space)替代IFS,而$*不会,因为其被认为一个字符串.个人实验后,感觉如此.但找不到可靠资料,所以故在此提问.

希望waker兄能给于帮助,先谢了.

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
5 [报告]
发表于 2006-02-22 16:11 |只看该作者
to johnny_jiang:
我看waker说的是对的,这个应该是word splitting的作用。
关于你在四楼的例子,那也很正常。因为IFS=:,Third:Arg和Fifth: :Arg被分割成Third,Arg和Fifth, Arg。for语句最后接受的是bash处理好的一个列表,此时它和bash的变量IFS是什么已经没有关系。试与下面的代码比较:
  1. for i in "$@"
  2. do
  3.   echo "$i"
  4. done
复制代码


至于var=$*
echo $var
输出的结果中没有一个:,那也是word spiltting的作用。试与下面代码比较:
  1. var=$*
  2. echo "$var"
复制代码

[ 本帖最后由 woodie 于 2006-2-22 16:17 编辑 ]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
6 [报告]
发表于 2006-02-22 17:04 |只看该作者
一个有趣的现象,字符串常量似乎不受word splitting影响:
  1. $ IFS=:
  2. $ for i in 1:2:3; do
  3.   echo "$i"
  4. done
  5. 1:2:3
复制代码

请与下面代码比较:
  1. $ IFS=:
  2. $ a=1:2:3
  3. $ for i in $a; do
  4.    echo "$i"
  5. done
  6. 1
  7. 2
  8. 3
复制代码

论坛徽章:
0
7 [报告]
发表于 2006-02-22 21:47 |只看该作者
原帖由 woodie 于 2006-2-22 17:04 发表
一个有趣的现象,字符串常量似乎不受word splitting影响:
  1. $ IFS=:
  2. $ for i in 1:2:3; do
  3.   echo "$i"
  4. done
  5. 1:2:3
复制代码

请与下面代码比较:
[code]$ IFS=:
$ a=1:2:3
$ for i in $a;  ...


感谢woodie兄,借予你的例子,其实就像waker说得,for i in 1:2:3是一开始就被metacharacter分隔了,而不是用IFS了。

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
8 [报告]
发表于 2006-02-23 07:56 |只看该作者
Word Splitting
       The shell scans the results of parameter expansion, command  substitu-
       tion, and arithmetic ......       The shell treats each character of IFS as a delimiter, and splits  the
       results  of  the  other expansions into words......

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
9 [报告]
发表于 2006-02-23 09:16 |只看该作者
我的測試結果如下:
kenny@x40:~> set -- "First Arg" "Second" "Third:Arg" "" "Fifth: :Arg"
kenny@x40:~> IFS=:
kenny@x40:~> echo $*
First Arg Second Third Arg  Fifth   Arg
kenny@x40:~> echo $@
First Arg Second Third Arg  Fifth   Arg

# 上面兩行沒差別

kenny@x40:~> echo "$*"
First Arg:Second:Third:Arg::Fifth: :Arg
kenny@x40:~> echo "$@"
First Arg Second Third:Arg  Fifth: :Arg

# 當使用 soft quote 之後, IFS 會不一樣

kenny@x40:~> var=$*
kenny@x40:~> var1=$@
kenny@x40:~> echo $var
First Arg Second Third Arg  Fifth   Arg
kenny@x40:~> echo $var1
First Arg Second Third Arg  Fifth   Arg

# 先經過 variable substitution , 結果沒差別.

kenny@x40:~> echo "$var"
First Arg:Second:Third:Arg::Fifth: :Arg
kenny@x40:~> echo "$var1"
First Arg Second Third Arg  Fifth   Arg

# 但放在 soft quote 中, 就不同了.
# 而且 "$var1" 跟 "$@" 不一樣, 在完成 variable substitution 後.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2006-02-23 10:57 |只看该作者
我觉得很好理解,
只要记住 $* 和 $@ 是两个特殊变量就行了。
只是因为这两个特殊变量在双引号中的解释有所不同而已。
       *      Expands to the positional parameters, starting from  one.   When
              the  expansion occurs within double quotes, it expands to a sin-
              gle word with the value of each parameter separated by the first
              character of the IFS special variable.
  That is, "$*" is equiva-
              lent to "$1c$2c...", where c is the first character of the value
              of  the IFS variable.  If IFS is unset, the parameters are sepa-
              rated by spaces.  If IFS is  null,  the  parameters  are  joined
              without intervening separators.
       @      Expands  to  the positional parameters, starting from one.  When
              the  expansion  occurs  within  double  quotes,  each  parameter
              expands to a separate word.
  That is, "$@" is equivalent to "$1"
              "$2" ...  When there are no positional parameters, "$@"  and  $@
              expand to nothing (i.e., they are removed).
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP