2012-08-16 93 views
5

这里第一篇文章,但一直是一个潜伏的年龄。我已经搜索了很长时间,但无法找到我想要的东西(许多不需要主题建议它的主题主题......)。不是新的awk或脚本,只是有点生疏:)awk:直接从awk脚本中设置环境变量

我想写一个awk脚本,它将设置shell env值,因为它运行 - 另一个bash脚本来拿起和使用后。我不能简单地使用awk的stdout来报告我想设置的值(即“export whatever = awk cmd here”),因为这已经指向awkscript创建的“结果文件”(加上我有多个变量可以导出无论如何,最终的代码)。

作为一个例子测试脚本,演示我的问题:

echo $MYSCRIPT_RESULT   # returns nothing, not currently set 
echo | awk -f scriptfile.awk # do whatever, setting MYSCRIPT_RESULT as we go 
echo $MYSCRIPT_RESULT   # desired: returns the env value set in scriptfile.awk 

scriptfile.awk内,我已经试过(不sucess)

1 /)建设和直接执行即席字符串:

{ 
    cmdline="export MYSCRIPT_RESULT=1" 
    cmdline 
} 

2 /)使用系统功能:

{ 
    cmdline="export MYSCRIPT_RESULT=1" 
    system(cmdline) 
} 

...但这些不起作用。我怀疑这两个命令是在awk执行的shell的内部创建一个子shell,并且按照我的要求(通过触摸文件作为测试来证明),但是一旦“cmd”/系统调用完成,子shell就会死亡,不幸的是采取我已经设定的任何东西 - 所以我的环境设置变化不会从“awk的调用者”的角度来坚持。

所以我的问题是,你如何真的在awk 内直接设置env变量,以便调用进程可以在awk执行完成后访问这些env值?它实际上可能吗?

除了上面的adhoc/system方法之外,我已经证明对我来说是失败的,我看不出如何做到这一点(除了将这些值写入某个“随机”文件的某个地方以供拾取和读取调用脚本,无论如何imo是有点肮脏),因此,帮助!

欢迎所有意见/建议/意见!

+0

不行。这是操作系统环境的一个基本规则,子进程可以改变它们的**环境,但不改变其父代的环境。你可以做的最好的是,(从shell脚本)'myParentVar = $(echo“$ myParentVar”| awk'{sub(/ xxxx /,“yyyy”,$ 0); print $ 0}')'(where sub (...)'是一个占位符,用于对$ myParetntVar进行任何修改。祝你好运。 – shellter 2012-08-16 14:04:40

+0

thx for the reply。我担心这会是这种情况(父母/孩子的环境设置和影响范围),所以认为我将不得不使用这些env变量的暂存文件来访问调用bash脚本。 thx用于确认我以为无论如何:( – user1603289 2012-08-16 14:19:17

+0

我也有这个问题,我所做的是写awk输出到一个临时文件,然后找到临时文件Works。不知道它是否优雅,但仍然非常unixy – qodeninja 2015-04-04 20:06:55

回答

4

您不能更改您的父进程的环境。如果

MYVAR=`awk stuff` 

是不可接受的,你所要求的是无法完成的。

+0

如上所述,你是对的,我试图调整从孩子的父env,这是一个禁忌(当我第一次发布时没有想到这种方式),这离开了2种向前移动的方法:或者让awk(stdout)返回你之后的结果,或者如果这些不可能(比如我自己)将这些值报告给一个文本文件,然后父文件可以检查这些文件以获取值试图传回(在我的情况下,使用env变量来告诉awk这个“更新文件”在哪里(使用mktemp),使得代码/实现中的事情变得更简洁:))。 – user1603289 2012-08-16 16:04:20

2

你可以做到这一点,但它有点混乱。由于awk不允许重定向到一个文件描述符,你可以使用一个FIFO或一个普通的文件:

$ mkfifo fifo 
$ echo MYSCRIPT_RESULT=1 | awk '{ print > "fifo" }' & 
$ IFS== read var value < fifo 
$ eval export $var=$value 

这是不是真的有必要分裂var和值;您可以轻松地awk打印“导出”并直接评估输出。

+0

在'gawk'中,您可以输出到在父shell中打开的备用文件描述符。另外,如果'stderr'没有被其他方式使用,它可以被用作输出值的方式。 – 2012-08-16 19:37:53

+0

fifo是一个有趣的想法,但是有可能(总是有)awk命令可能无法返回任何内容(错误条件),然后在fifo读取时阻止执行(awk脚本不是单行 - 远从中!)。我也喜欢使用stderr的想法,但是当脚本失败时,stderr应该保持“清除代码”的时间,因为我们不想在运行时将gibber引入到程序中,因此我不认为这是一个好主意使用任何一个 - 但感谢无论如何(我确实说过所有的想法欢迎) - 我用临时文件去了,这只是一个更安全的 – user1603289 2012-08-17 13:17:02

+0

直到今天我从来没有听说过mkfifo。谢谢! mkfifo + nc =是! – qodeninja 2015-04-04 20:11:15

1

像在 Set variable in current shell from awk

unset var 
var=99 
declare $(echo "foobar" | awk '/foo/ {tmp="17"} END {print "var="tmp}') 
echo "var=$var" 
var= 

awk的END子句是必不可少的,否则,如果没有到申报模式匹配转储当前环境标准输出和不改变描述您还可以使用的东西你的变量的内容。

可以通过用空格分隔来设置多个值。

declare a=1 b=2 
echo -e "a=$a\nb=$b" 

注意:声明只是bash,对于其他shell,使用相同语法的eval。