2012-08-16 127 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。