系统调用、AWK 和引入外部输入

系统调用、AWK 和引入外部输入
awk '{ TEMPVAR="/usr/bin"; printf("%s", system("ls $TEMPVAR")); }' empty

在此示例中,我尝试将变量引入调用TEMPVARsystem。我该怎么做?

我的目标是:我试图date -d $0 +%ssystem文件每一行发生的调用中使用。但是,我正在努力解决如何将该$0值放入系统调用中的问题。

答案1

awk可以使用ENVIRON特殊数组访问环境变量。但是,虽然您可以为该数组的元素赋值,但它不会在awk's system| getline或执行的命令的环境中传递print |。该数组仅ENVIRON用于awk得到它传递的环境变量的值。

您可以执行: ,但请注意,传递给's (或或)system("ls " var)的字符串实际上是作为参数传递给 的,因此它被解释为 shell 代码。awksystem()print || getlinesh -c

例如,如果awk var变量包含foo;rm -rf /,则不会告诉ls列出调用的文件"foo;rm -rf /",而是列出调用的文件foo,然后rm运行命令。

var因此,您可能需要转义该变量中 shell 特有的所有字符。

例如,这可以通过以下方式完成:

awk '
  function escape(s) {
    gsub(/'\''/, "&\\\\&&", s)
    return "'\''" s "'\''"
  }
  {
    cmd = "date -d " escape($0) " +%s"
    cmd | getline seconds
    close(cmd)
    print seconds
  }'

虽然这意味着每行运行一个 shell 和一个date命令,但您也可以使用 shell 本身来读取文件:

while IFS= read <&3 -r line; do
  date -d "$line" +%s
done 3< the-file

答案2

如果您将 Awk 变量传递给系统,你需要 shell 引用它:

function quote(str,   d, m, x, y, z) {
  d = "\47"; m = split(str, x, d)
  for (y in x) z = z d x[y] d (y < m ? "\\" d : "")
  return z
}

例子:

system(sprintf("date -d %s +%%s", quote($0)))

来源

相关内容