[Happy BASH] 关于BASH程序的输入方式小结

在*NIX环境中,内部命令或外部命令(Utility)支持以下三种输入方式:

1. 命令自己提供的输入参数,更准确地说是处理的对象,譬如AWK中的文件。不是那些控制参数。

2. 从STDIN输入。

3. 从文件重定向到STDIN作为输入。


对于2,用户每输入一行(ENTER键结束),程序就输出它。而3不同,看到重定向操作符,SHELL会将文件的输入重定向到STDIN中,作为命令的标准输入,所以对于程序来说,这个过程是透明的。程序一次性的读入文件的所有内容作为输入,然后处理,不管文件中有多少行。

PIPE(通道)提供了一种方式,将一个程序的STDOUT连接到另一个程序的STDIN,这样前一个程序的标准输出,后一个程序的输入就可以看到。管道连接的2个程序几乎是同时运行的,区别于&&或","连接的2个程序,而且标准输出默认是行缓冲输出的,所以说,前一个程序的一行输出,在后一个程序中标准输入中就可以看到一行输入。


而对于1,这个是程序特别的。程序需要什么样的输入参数,程序自己知道。在*NIX中,标准的输入是以WHITESPACE作为分隔符的。一般来说,程序是一个一个参数来处理的,所以程序就可以捎带N多输入参数,但是这个是在系统中是有限制的( getconf ARG_MAX)。我们可以通过xargs命令,然后连同PIPE将一个程序的输出,转化为一个标准的参数输入列表,只要某个程序支持标准的参数列表输入,那么用这种方式给程序提供参数输入就可行。譬如

find . -name '*.pl' | xargs 

当查找出来的文件中包含换行符时,我们需要为find命令加上-print0选项,将每项输出结尾的\n替换成NULL,然后在xargs命令中采用-0选项来将NULL作为输入项的分隔符。这样就能争取的得到每项的输入。xargs默认是以WHITSPACE作为分隔符。

find ./ -name '*.txt' -print0 | xargs -0 -n 1 cat

同时-print0和-0选项的结合,可以消除文件中包含WHITESPACE的问题。

加入txt文件有2个"a b.txt"和"a.txt", find默认给出一行一个文件的输出。

$ find ./ -name '*.txt'
./a b.txt
./a.txt
输入到xargs中,它会默认按照WHITESPACE分隔,比如:

$ find ./ -name '*.txt' | xargs -n 1
./a
b.txt
./a.txt
$ find ./ -name '*.txt' | xargs -n 2
./a b.txt
./a.txt
$ find ./ -name '*.txt' | xargs -n 3
./a b.txt ./a.txt
-n 是将输入中的多少个项组成一个参数列表。所以如果那 xargs输出的参数列表来执行其他命令,大多数会失败,因为有些项已经被WHITESPACE分隔开了。

需要说明的是,有些程序提供了“-” option,支持从标准输入中获取输入参数,譬如AWK程序

awk 'print' a.txt -
先处理a.txt,然后再循环处理标准输入。



你可能感兴趣的:([Happy BASH] 关于BASH程序的输入方式小结)