免费注册 查看新帖 |

Chinaunix

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

关于IFS的疑问  关闭 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-03-15 21:31 |只看该作者 |倒序浏览
正在看网中人的13问,看到IFS有一些疑问,请教大家:

1、如果我没保存原IFS,怎么用语句直接设置IFS
IFS="  \n\t"
这样设对吗,是恢复默认的吗??

2、我看说明中有:
IFS=
IFS=;
是一样的意思,我不明白既然一样为什么要用第二种形式呢??有什么特殊意义吗??还是仅用来区别与IFS=";"的不同。
第二种形式中的分号怎么解释??

3、默认IFS时如果
A="   aaa"
echo $A
结果当然是
aaa
前面没有空格
但是
A=";;;;aaa"
IFS=";"
echo $A 时
结果却是
    aaa
前面有四个空格,按道理不是应该没有空格吗?这是怎么回事呢??

4、文件b的内容是
echo $*
echo $1

#IFS=";"
#./b  111    22222

结果和不设IFS是一样的,都是
111 2222    (--中间一个空格)
111
为什么在执行命令时IFS不起作用呢??
我想的是如果起了作用,shell不就把整行看做无参数的命令了吗,shell就应该说找不到该命令了,呵呵,当然不想这样,我只是试验一下,这里为什么就不起作用了呢???

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2005-03-15 22:53 |只看该作者

关于IFS的疑问

1) 你可先將 IFS 存起來: old_IFS="$IFS"
要取回時再設 IFS="$old_IFS"
(記的雙引號一定要設哦)

2) 若有兩個 command 打在同一行就用到.

3) 這要扯到 command 與 shell 在 IFS 的認定及處理的差異了.
嗯, 我也講不出個所以然... sorry.
我認為 echo 是在 subshell 裡執行的, 而 subshell 在 initial 時會採用原有 IFS .
不過, 我不確定啦.
你可比較如下兩行:
IFS=";"; echo $A
IFS=";" echo $A
差別在於少了一個 ;  , 也就是第二行改變了 subshell 的 IFS 而第一行則沒有.

4) 你用 "$*" 才能發現有何不同, 且將 IFS 設在 b 裡面, 再比較如下:
./b 111 & & 222
./b "111 & & 222"

在 man bash 裡, 關於 $* 的說法如下:
  1.         *      Expands to the positional parameters, starting from
  2.               one.   When  the  expansion  occurs  within  double
  3.               quotes,  it expands to a single word with the value
  4.               of each parameter separated by the first  character
  5.               of  the  IFS  special  variable.   That is, "$*" is
  6.               equivalent to "$1c$2c...", where  c  is  the  first
  7.               character of the value of the IFS variable.  If IFS
  8.               is unset, the parameters are separated  by  spaces.
  9.               If  IFS  is null, the parameters are joined without
  10.               intervening separators.
复制代码

论坛徽章:
0
3 [报告]
发表于 2005-03-16 03:31 |只看该作者

关于IFS的疑问

IFS 的确叫人误解, 问题也不少.  最好是不要改.

原帖由 "li2002" 发表:
3、默认IFS时如果
A="   aaa"
echo $A
结果当然是
aaa
前面没有空格
但是
A=";;;;aaa"
IFS=";"
echo $A 时
结果却是
   aaa
前面有四个空格,按道理不是应该没有空格吗?这是怎么回事呢??


这是由于作为 IFS 的空白字符 ( blank, tab, newline) 与其他 IFS 字符行为不同:

1.  IFS 空白在输入的开始和结束处忽略。
2.  输入中每个非 IFS 空白的 IFS 字符,以及任何相邻的 IFS 空白,定界一个字段。
3. 非零长度 IFS 空格对字段进行定界。

更多例子,参考 Advanced Bash-Scripting Guide

http://www.tldp.org/LDP/abs/html/internalvariables.html#IFSH
http://www.tldp.org/LDP/abs/html/internalvariables.html#IFSEMPTY


原帖由 "li2002" 发表:


我想的是如果起了作用,shell不就把整行看做无参数的命令了吗,shell就应该说找不到该命令了,呵呵,当然不想这样,我只是试验一下,这里为什么就不起作用了呢???


1. IFS 只对参数扩展有作用, $* 是 $1 - $n, 不包括 $0

2. IFS 对参数位置无作用. 参数位置由空白字符及有无" " 决定

所以不可能出现你想象的情况.

原帖由 "li2002" 发表:

4、文件b的内容是
echo $*
echo $1

#IFS=";"
#./b  111    22222

结果和不设IFS是一样的,都是
111 2222    (--中间一个空格)
111
为什么在执行命令时IFS不起作用呢??


如 netman 所言,IFS 语句应加在程序中.

在 "$*" 扩展时行为不同 (如较新版本的 bash, ksh). 这是 POSIX 标准.

但由于历史原因, 有些版本的 shell  并不按 man page 中所声明的那样扩展,
而是只用空格,  这样有无 IFS 对 "$*" 无影响.

refer to: POSIX white paper
<<Shell Command Language: Migrating from the System V Shell to the POSIX Shell>>

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
4 [报告]
发表于 2005-03-16 10:37 |只看该作者

关于IFS的疑问

呵... 受教受益!

感謝 lightspeed 兄的說明及相關資訊!  ^_^

论坛徽章:
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
5 [报告]
发表于 2005-03-16 10:42 |只看该作者

关于IFS的疑问

行家伸伸手,便知有没有,学到了

论坛徽章:
0
6 [报告]
发表于 2005-03-16 14:05 |只看该作者

关于IFS的疑问

FT!写了一大段话因为session超时没有了,5555~~~~
这是第二次写:
谢谢网中人和版主的回答,真是热心人啊!!
不过还有些问题不明白:
网中人回答我第三问
A=";;;;aaa"
IFS=";"
echo $A 时
结果却是
   aaa


  1. 你可比較如下兩行:
  2. IFS=";"; echo $A
  3. IFS=";" echo $A
  4. 差別在於少了一個 ;  , 也就是第二行改變了 subshell 的 IFS 而第一行則沒有

  5. .

复制代码

我的结果是
$A=";;;;aaa"
$ IFS=""
$ IFS=";" echo $A
;;;;aaa

$ IFS=""
$ IFS=";";echo $A
aaa

结果好像和netman说的意思相反呢,
我想问一下,这两种情况有何不同??无分号分隔是一个子进程里执行,有分号的在两个子进程里执行??
netman的意思是一个进程的IFS变量由其父进程决定,而不是由本进程中设置的IFS决定??

还有第四问中回答说将IFS设置放在b中,这与写在命令行中有何区别?这还应该涉及到子进程的问题吧。如果b中有两行命令,在执行./b后,系统会产生一个子进程(父进程等待),是在这一个子进程中依次执行b中的命令行,还是在执行每行时都再产生各自的子进程执行命令呢??这与在命令行中一个一个命令输入执行又有什么区别??

netman说的subshell与我说的子进程是一个意思吧??

再帮我分析一下两个语句间是空格、分号、&&、||的进程执行情况吧。

论坛徽章:
0
7 [报告]
发表于 2005-03-16 14:15 |只看该作者

关于IFS的疑问

lightspeed 说的IFS的whitespace和用其他字符做IFS处理是不一样的,看了链接我明白了,是不能用whitespace类推,但我觉得还是不能很好的解答为什么要出现4个空格的问题。
是不是其他字符做IFS时,在字符串中与IFS相同的字符显示时都由空格替代??这是一条规则??

老大说的这一句:
  1.      

  2. 2. IFS 对参数位置无作用. 参数位置由空白字符及有无" " 决定
复制代码


是什么意思啊??跟在命令后的不都是参数吗?是指对$*,$1....$n不起作用是吗??对$*来说,分隔符是不能指定的是吗??

论坛徽章:
0
8 [报告]
发表于 2005-03-17 14:10 |只看该作者

关于IFS的疑问

up一下

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
9 [报告]
发表于 2005-03-17 21:03 |只看该作者

关于IFS的疑问

呵, 太深了...
我也答不上來~~~  ^_^

论坛徽章:
0
10 [报告]
发表于 2005-03-17 21:48 |只看该作者

关于IFS的疑问

的确,lightspeed讲得很明白了。
[quote]原帖由 "li2002"]但我觉得还是不能很好的解答为什么要出现4个空格的问题。[/quote 发表:

关于这一点,可以这么理解:
  1. A=";;;;aaa"
  2. IFS=";"
  3. echo $A
复制代码

在最后一条命令中,传给echo的命令行参数为$1="";$2="";$3="";$4="";$5="aaa"。
执行过程等效于
  1. printf "%s" "$1"
  2. for arg in "$2" "$3" "$4" "$5"; do
  3.     printf " %s" "$arg"
  4. done
  5. printf "\n"
复制代码

也就是说,在除第一个参数外的每个参数前,echo自动加一个空格与前一参数分隔。这样就产生了四个前导空格。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP