2013-01-21 17 views
1

我試圖從python構建和執行csh腳本。在Python中創建和執行tcsh腳本

我的代碼產生什麼看起來像一個正確的腳本,並os.system("my_script.csh")返回「0」,但劇本不除非我進入它使用vim並重新保存(手動執行其中的任務手動更改腳本中的任何內容 - 我甚至不輸入'插入'模式)。在vim中重新保存的是什麼,這是不是在我的代碼中完成,是否有可能做到這一點?

這裏是我的代碼的相關部分:

grabmeName = '%sgrabme%s.csh'%(dirNames['grabmes'],uniqID) 
if not os.path.exists(grabmeName): 
    open(grabmeName,'w').close() 
    os.chmod(grabmeName,0777) 
    with open(grabmeName,'a') as f: 
     f.write("#!/bin/csh -f\n") 
     f.write("echo 'hello'") 
    os.system(grabmeName) 
+0

你似乎有一個壓痕錯誤。你能否檢查你的代碼,並確保你在這裏的縮進*完全像你的代碼一樣?我至少可以想到一種情況,可能會導致您看到的行爲取決於縮進。 。 。 – mgilson

+0

謝謝,這是一個錯字。 Editted。 – user1824335

+0

爲什麼打開'a'ppend而不是'w'rite文件? – sotapme

回答

2

主要問題是shell中的每一行都需要以\n結尾才能執行,即使是最後一行。您可以將\n添加到"echo 'hello'"字符串的末尾。這可能是csh中的一個錯誤,因爲bash和朋友沒有這個問題,但是如果你想使用csh,你必須適應它。

當你在vim中保存一個文本文件時,如果沒有一個開頭的話,它會在文件中添加一個尾隨換行符。您可以通過預先保存文件的副本,並運行diff,看看有什麼變化VIM驗證這一點:

$ cat blah-grabme-12.csh 
#!/bin/csh -f 
echo 'hello'$ cp blah-grabme-12.csh blah-grabme-12.csh.orig 
$ vim blah-grabme-12.csh 
┌────────────────────────────────────────────────────────────────────────────────┐ 
│#!/bin/csh -f                 │ 
│echo 'hello'                 │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│~                    │ 
│:wq❚                   │ 
└────────────────────────────────────────────────────────────────────────────────┘ 
$ diff -u blah-grabme-12.csh.orig blah-grabme-12.csh.orig 
--- blah-grabme-12.csh.orig 
+++ blah-grabme-12.csh 
@@ -1,2 +1,2 @@ 
#!/bin/csh -f 
-echo 'hello' 
\ No newline at end of file 
+echo 'hello' 

您可以關閉VIM的這種行爲在你~/.vimrc如果你願意的話。請參閱:help 'eol' vim幫助。

另一個潛在的問題是,如果filename是一個非空路徑,即system(filename)只會工作,具有在/它,或者如果.在系統$PATH

此外,通過使用os.open()而不是open(),您可以在文件創建時設置文件權限。在這裏它可能沒有太大區別,但在許多情況下,創建文件然後更改其權限會導致security vulnerabilityThis stackoverflow question顯示瞭如何做到這一點。


全部放在一起,你會得到這樣的事情:

import os 
import os.path 

grabmeName = 'blah-grabme-12.csh' 

with os.fdopen(os.open(grabmeName, os.O_WRONLY | os.O_CREAT, 0700), 'w') as f: 
    f.write("#!/bin/csh -f\n") 
    f.write("echo 'hello'\n") 
os.system(os.path.abspath(grabmeName)) 
+0

太棒了,謝謝。你的版本如何測試文件是否存在?我認爲'os.O_WRONLY | os.O_CREAT'part這樣做,但是你的腳本會運行該命令,即使它已經被創建過。我需要測試它是否存在,因爲我正在運行此腳本的多個實例,並且不希望不必要地重新運行該命令。 – user1824335

+0

謝謝,很高興你喜歡它!你可以把'if not os.path.exists(grabmeName):'換回來。我解決了這個問題,因爲它反覆測試腳本煩人:我會更改Python腳本,但它會運行舊版本的shell腳本... – andrewdotn

0

你應該結帳subprocess它顯示了很多例子。

output=`mycmd myarg` 
# becomes 
output = check_output(["mycmd", "myarg"]) 

正如你想捕獲命令的輸出,而不僅僅是返回狀態。

+0

我實際運行的腳本有一點涉及(儘管問題仍然出現在問題中的'echo'hello'命令) - 我想將它保存爲獨立可執行文件,以便它可以在需要時重新運行。 – user1824335

+0

雖然你想動態創建一個腳本,運行它並捕獲它的輸出。我之前已經有了一個腳本,DOS腳本的結尾會阻止腳本運行,這可能是爲什麼進入vim並更正行結尾的原因。前後用'od -c'檢查。 – sotapme

+0

我將它的輸出保存到文件系統的腳本中,所以我不需要輸出 - 我只提到它聲明腳本正在執行。 – user1824335