当IFS设置为某项时,如何将新行传递给argv参数,命令输出的方式在这里?
注意,我正在做此测试,以试图弄清楚unix中的工作方式。不是我实际上想要在argv元素中换行!
我有显示argv的程序。
$ cat blah.c
#include <stdio.h>
int main(int argc, char *argv[]) {
int i = 0;
while (argv[i]) {
printf("argv[%d] = %s\n", i, argv[i]);
i++;
}
return 0;
}
$
$gcc blah.c -o blah
$
[我注意到,如果我将IFS设置为等于某个值,或者甚至将IFS=
设置为等于或IFS = \n
,则将默认值unset IFS
设置为除此以外的任何值。 IFS =“ {”,然后命令输出扩展将多行设置为一个参数,例如到argv [1]
ubuntu@ubuntu:~/aaa$ IFS="{"
ubuntu@ubuntu:~/aaa$
ubuntu@ubuntu:~/aaa$ ./blah `find .`
argv[0] = ./blah
argv[1] = .
./blah
./blah.c
./b
./a
现在,如果我尝试将参数传递给./blah,则无法在argv [1]中获得多行! (我有兴趣做为测试)
ubuntu@ubuntu:~/aaa$ ./blah "g h"
argv[0] = ./blah
argv[1] = g h
ubuntu@ubuntu:~/aaa$ ./blah g h
argv[0] = ./blah
argv[1] = g
argv[2] = h
ubuntu@ubuntu:~/aaa$ ./blah g\n h
argv[0] = ./blah
argv[1] = gn
argv[2] = h
ubuntu@ubuntu:~/aaa$ ./blah "g\n h"
argv[0] = ./blah
argv[1] = g\n h
ubuntu@ubuntu:~/aaa$
所以,find .
扩展到什么,导致将多行发送到argv [1]?
这样,当我尝试将参数传递给程序时,我无法重现这种现象?
当IFS不包含空格(空白)时,命令行上的扩展名不会在这些空格上分开:
$ var="Hello world"
$ set -x; printf '%s\n' $var; set +x
+ printf '%s\n' Hello world
Hello
world
+ set +x
您可以从[+
)输出(-x
输出中看到,参数$var
,一个参数,在空格上分割,然后打印为多个参数。
如果IFS被更改:
$ IFS=o
$ set -x; printf '%s\n' $var; set +x
+ printf '%s\n' Hell ' w' rld
Hell
w
rld
+ set +x
参数的数量和值也会改变。
find .
发生的情况是,当IFS包含换行符时,是的,IFS的默认值应包含一个换行符:
$ printf '%s' "$IFS" | od -tcx1
0000000 \t \n
20 09 0a
0000003
find的输出。 (其中包括几个换行符)在换行符上进行划分(有效地,删除了换行符)
$ printf '<%s>\n' `find .`
<.>
<./hello>
如果当前目录(pwd)中仅存在一个名为hello
的文件。
但是,如果IFS中的换行符被删除,则输出不会被分割,并且它只是one字符串(包含换行符,是):
$ IFS=x
$ printf '<%s>\n' `find .`
<.
./hello>
与引用find ,
的扩展名相似:
$ IFS=$' \t\n' # return IFS to default in bash.
$ printf '<%s>\n' "`find .`"
<.
./hello>
所以,要回答标题的最初问题:
只需使用正确的引号:
$ var='hello world
and some other'
$ printf '<%s>\n' '$var' "$var" $var
<$var>
<hello world
and some other>
<hello>
<world>
<and>
<some>
<other>
有帮助吗?