2017-02-23 66 views
0
('cd /etc/squid/ && new_val=9 && old_val=3 && sed -i "s/$old_val/$new_val/g" *.conf') 

這給了我一個錯誤與變量桑達工作不正是我想要的工作

ExecutionError: sed: -e expression #1, char 0: no previous regular expression

我不知道是什麼問題。

以上內容正在Python腳本中使用。

+0

我知道我可以使用子,但我想知道我爲在這裏失蹤.. – user2939055

+0

對我的作品罰款的命令行。我懷疑Python可能是這裏的問題。 – miken32

+0

@ miken32:這不是Python,它是濫用'bash'。它在命令行中不起作用,簡單的repro:'new_val = 9 && old_val = 3 sed「s/$ old_val/$ new_val/g」<(echo「1234567890」)' – ShadowRanger

回答

2

將其更改爲:

('cd /etc/squid/ && new_val=9 && old_val=3 && sed -i "s/$old_val/$new_val/g" *.conf') 

變量賦值需要從sed一份單獨聲明。當你在一個語句的開頭放置一個變量賦值時,它只設置一個由子進程繼承的環境變量。但是您需要將變量擴展到原始shell,因此您需要在執行sed命令之前設置該變量。

-1

事實上,我發現了一些工作,將每個變量放在單引號中,並轉義單引號。

+0

你能解釋/提供解決方案代碼嗎?我沒有看到一個明顯的方式,單引號可以幫助你(你可以使用它們來避免bash變量插值,但是如果它接收到'$'名字,我不認爲'sed'會爲你做到這一點,它會將它們視爲文字字符串)。 – ShadowRanger

0

您的問題是:

old_val=3 sed "s/$old_val/$new_val/g" 

是依靠shell來擴展變量,而不是sed。但通過命令前綴設置變量隻影響命令的環境,而不是bash,所以old_val從不爲定義的字符串插值的目的。每bash reference manual(強調):

The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described in Shell Parameters. These assignment statements affect only the environment seen by that command.

所以如果sed試圖從自己的環境讀old_val會看到正確的值。但是sed正在接收是通過插值後的字符串,這是s//9/g,因爲bash的插值並沒有看到old_val(只存在於sed)。

要解決,通過一個單獨的命令進行分配集合在bash的變量,而不是sed前綴:

('cd /etc/squid/ && new_val=9 && old_val=3 && sed -i "s/$old_val/$new_val/g" *.conf') 

或者更準確地說,你應該避免依賴shell=True(這是危險/容易濫用)。即使必須使用sed,所有你使用可以在Python的層做殼的東西:

import os 

# Get the (unqualified) names of all the entries with the desired name 
files = [f for f in os.listdir('/etc/squid') if f.endswith('.conf')] 
# Run w/o shell=True, in list form, letting Python handle the working directory 
# and variable formatting 
subprocess.Popen(['sed', '-i', 's/{}/{}/g'.format(old_val, new_val)] + files, cwd='/etc/squid') 

此具有相同的行爲(在/etc/squid工作,並將不合格的文件名,這樣你就贏了如果深度嵌套目錄中有很多文件,則不會有新的命令行長度問題)。

當然,你可以走得更遠,只需使用the fileinput module也可以在Python中完成sed的工作;它具有編輯文件的功能,就像sed(儘管如果文件具有有意義的大小,它可能會稍微慢一些)。