7

我有一个理论问题:

1)getline()的系统如何传递一个变量?

awk 'BEGIN{var="ls"; var | getline var; system("echo $var")}'

2)如何为输出系统(“ls”)分配一个变量并在awk中打​​印结果?

awk 'BEGIN{var="system("ls")"; print '$var'}'

3)你可以在系统中分配一个变量(var =“ls”)并在awk中打​​印结果吗?

awk 'BEGIN{system(var="ls"); print "'"$var"'"}'

感谢您的信息。

编辑:

torek:谢谢你的回复。

我知道在第一个示例中,您可以这样做:

awk 'BEGIN { while ("ls -l" | getline var) system("echo " var  );}'

对于此应用程序,您不能从 system() 分配变量输出吗?如本例所示:

awk 'BEGIN {var="ls -l"; system(var); print var}'
4

1 回答 1

15

我想你看错了。awksystem只接受任何旧字符串,所以给它一个,例如:

system("echo " var);  # see side note below

(请记住,在 awk 中,字符串是通过邻接连接的)。此外,system只需运行一个命令;要捕获其输出,您需要使用getline,类似于您的问题 #1。

如果要读取所有输出,则ls需要循环遍历结果getline

awk 'BEGIN { while ("ls" | getline var) print "I got: " var; }'

由于这仅定义了一个BEGIN动作,awk因此将启动、运行ls、收集每个输出行并打印它,然后退出。


旁注:对传递给 shell 的变量要非常小心(这包括调用system和左侧的项目| getline,以及现代变体中的一些其他情况——awk任何运行命令的东西)。反引号、$(command)和分号都可以允许用户调用任意命令。例如,在上面的system("echo " var)示例中,如果var包含; rm -rf $HOME命令变为echo ; rm -rf $HOME,这几乎肯定不是您想要发生的事情。

您可以检查“坏”字符和任一对象,或引用它们。现代 8 位干净的 shell 应该只需要引用引号本身(为了句法有效性),$, <, >, |, 和`. 如果您使用单引号来引用参数(使它们显示为单个“单词”),您只需转义单引号。有关更多详细信息,请参阅此 unix.stackexchange.com 答案


另一个旁注:我倾向于在我的 awk 脚本中添加“不必要的”分号,使它们在语法上看起来更像 C。几十年前的旧习惯。

于 2012-04-04T09:49:11.657 回答