2013-08-03 22 views
3

我問,因爲我最近對正在執行的KornShell(ksh)腳本進行了更改。在我保存更改後不久,執行過程失敗。從錯誤消息來看,它看起來好像正在運行的進程已經看到了我的一些變化 - 但不是全部 - 。這強烈暗示當調用shell腳本時,整個腳本不會被讀入內存。被調用時是否全部讀取shell腳本?

如果這個結論是正確的,則表明應該避免對正在運行的腳本進行更改。

$ uname -a 
SunOS blahblah 5.9 Generic_122300-61 sun4u sparc SUNW,Sun-Fire-15000 
+0

此問題可能是[已經回答的問題]的副本(http://stackoverflow.com/questions/3398258/edit-shell-script-while-its-running)。 – LRA

+2

Shell腳本是以塊的形式讀取的,所以如果有一個大的循環,那麼循環的所有材料都會被讀取,但超出的材料可能還沒有被處理。我當然在運行時遇到了shell腳本的更改,導致出現問題 - 避免它。但它並不總是會發生,並取決於shell,平臺和腳本。它也可能受'塊大小'的影響; shell可以輕鬆地讀取塊中的文件,並在當前不再需要讀取更多內容時停止。 –

+1

@Jonathan:斷言shell腳本在塊中讀取符合我的經驗,並且可以解釋執行腳本爲什麼選擇了我的更改的不完整版本。 – Kirby

回答

1

號Shell腳本讀任一條線由行,或命令由命令後跟; S,與塊的例外如if ... fi塊,其被解釋爲一個塊:

shell腳本是一個包含shell命令的文本文件。如果在調用Bash時使用這樣的 文件作爲第一個非選項參數,並且 既不提供-c nor -s選項(請參閱調用Bash),則Bash 將從該文件讀取並執行命令,然後退出。此模式的 操作會創建一個非交互式shell。

可以證明,對於一個if塊的fi殼等待通過在命令行上手動輸入他們執行命令。

http://www.gnu.org/software/bash/manual/bashref.html#Executing-Commands

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Scripts

+0

不,它們通常以取決於所討論的shell的輸入緩衝區的塊讀取,例如一次處理128個字節。 – mirabilos

+0

當然,它們是以塊的形式讀取的,但shell是自上而下的命令,這意味着它尋找控制結構以查看它是否應該繼續。所以它可能已經從文件中讀取了下一個'$ BUFSIZE'字節,但是如果它看到一個換行符和'退出255',它將被釋放。你是對的。 –

0

這很有趣,我知道大多數OS'es,不讀任何腳本在內存中的全部內容,並從磁盤運行它。否則可以在運行時更改腳本。我不明白爲什麼這樣做了,鑑於:

  • 腳本通常非常小(不佔用反正很多內存)
  • 在某一點,而在這個線程顯示,人們會開始製作一個已反正運行

修改腳本但是,承認這一點,這裏的一些思考:如果你決定一個腳本不正常運行(因爲你正在編寫/變更/調試),做你關心該腳本的其餘運行?您可以繼續進行更改,將其保存並忽略當前運行完成的所有輸出和操作。

但是..有時候,這取決於有問題的腳本,後續運行相同的腳本(修改與否)可能會成爲問題,因爲當前/上一次運行正在進行異常運行。它通常會跳過一些東西,或者是跳到腳本中的某些部分,但它不應該。這可能是一個問題。它可能使「事物」處於不良狀態;特別是涉及文件操作/創建的時候。

因此,作爲一般規則:即使操作系統支持該功能,最好讓當前運行完成,然後保存更新後的腳本。你可以改變它,但不要保存它。

它不像在DOS的舊時代,你實際上只有一個屏幕在你面前(一個DOS屏幕),所以你不能說你需要等待運行完成,然後才能打開再次文件。

0

不,他們不是,有很多很好的理由。 你應該記住的一件事是即使有一些相似之處,shell也不是解釋器。殼被設計用於處理一系列命令。無論是TTY,PIPE,FIFO還是插座。 shell從其資源行逐行讀取,直到內核返回EOF。 大多數shell沒有額外的解釋文件支持。他們會像使用終端一樣使用文件。 事實上,這被認爲是一個很好的功能,因爲你可以做這樣有趣的事情How do Linux binary installers (.bin, .sh) work?

你可以使用一個二進制文件並預先安裝shell腳本。你不能用口譯員來做這件事。因爲它解析整個文件,或者至少它會嘗試並失敗。一個shell只會逐行解釋它,並不關心文件末尾的垃圾。您必須確保腳本的執行在到達二進制部分之前終止。