
我(真的)是函數式程式設計的新手(事實上只使用 python 接觸過它),但對於 shell 環境中的一些清單密集型任務來說似乎是一個好方法。
我想做這樣的事情:
$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]
有沒有這些功能的 Unix shell?或者也許有一些功能允許從 python 中輕鬆存取 shell(命令、env/vars、readline 等)(這個想法是使用 python 的交互式解釋器作為 bash 的替代品)。
編輯:
也許一個比較例子可以澄清這一點。假設我有一個由以下組成的列表目錄/文件:
$ FILES=( build/project.rpm build/project.src.rpm )
我想做一個非常簡單的任務:將所有文件複製到距離/並將其安裝在系統中(這是建置過程的一部分):
使用bash:
$ cp ${檔案[*]} dist/ $ cd dist && rpm -Uvh $(for f in ${files[*]}; do basename $f; done))
使用“pythonic shell”方法(注意:這是虛構的程式碼):
$ cp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist'
你能看到差異麼 ?這就是我所說的。怎麼還不能退出內建這些東西的外殼呢?在 shell 中處理清單確實很痛苦,即使它是如此常見的任務:檔案清單、PID 清單、所有內容的清單。
還有一個非常非常重要的一點:使用大家都知道的語法/工具/功能:sh 和 python。
IPython 似乎朝著一個好的方向發展,但它很臃腫:如果 var name 以 '$' 開頭,它會執行此操作,如果 '$$' 則執行此操作。它的語法不“自然”,有很多規則和“解決方法”([ ln.upper() for ln in !ls ]
-->語法錯誤)
答案1
有一個方案外殼這可能非常接近您正在尋找的內容。我自己沒用過。
更新 :
我剛剛安裝並親自嘗試過。看來,scsh 更像是一種互動式Scheme 解譯器和腳本語言,而不是真正有用的互動式shell。你不能只輸入
echo hello
語法似乎是
(run (echo hello))
我花了幾分鐘的谷歌搜尋才找到這一點。第一個例子這裡是:
gunzip < paper.tex.gz | detex | spell | lpr -Ppulp &
翻譯過來就是:
(& (| (gunzip) (detex) (spell) (lpr -Ppulp)) (< paper.tex.gz))
但這並沒有告訴你如何運行簡單的外殼命令。
4.6 我可以使用 scsh 作為互動式 shell 嗎?
好吧,從技術上講,您可以:只需執行「scsh」命令,您將進入具有所有可用 scsh 功能的Scheme 48 會話。然而,這絕對不適合互動式工作:沒有命令列編輯,沒有命令列歷史記錄,沒有文件/函數名稱完成,沒有簡潔的語法等。
為了緩解這些問題,Martin Gasbichler 和 Eric Knauel 編寫了 Commander S,它運行在 scsh 之上並提供舒適的互動環境。它的新穎功能之一是它可以理解許多 Unix 命令的輸出,並允許使用者以有用的方式瀏覽和操作它。有關 Commander S 的更多資訊可以在描述它的論文中找到: http://www.deinprogramm.de/scheme-2005/05-knauel/05-knauel.pdf 有關如何取得和安裝 Commander S 的說明可從 scsh 網站取得:http://www.scsh.net/resources/commander-s.html
所以也許這才是真正的答案。
答案2
在直接回答問題的類別中,有ES外殼旨在作為 Bash 和 Zsh 等的功能替代品。
其次,在幫助你編寫更多功能的標準 shell 方面,可以考慮學習 pipelinemill 技術:
who | while read username
do
cat <<EOF | grep $username
nic
mark
norman
keith
EOF
done | while read username
do
echo "you have an answer on superuser.com" | mail -s "well done" $username
done
第一個 while 迴圈是函數式迴圈keep
(僅傳遞迴圈中出現的非空值),第二個迴圈是函數式迴圈(each
僅用於副作用的映射)。
這對於 shell 中的 fp 來說是一個巨大的提升。
可以在 shell 中以更 fp 的風格表達許多東西,但它並不像想像的那麼容易。儘管我們都經常使用它們,但似乎對製造更好的外殼沒有太多興趣。
答案3
標準的 Bourne 風格 shell(sh
、bash
、ksh
等)已經允許您執行以下操作:
for repo in repo1 repo2 repo3 ; do git clone $host/$repo ; done
do
(注意和之前需要加分號done
。)此外,在bash
和 其他 shell 中,如果$repo
只在命令中出現一次,您可以編寫:
git clone $host/{repo1,repo2,repo3}
答案4
Scheme Shell,scsh,確實不錯。
正如 Keith Thompson 所指出的,它作為互動式 shell 並沒有什麼用處(儘管 Commander S 看起來像是一個有趣的實驗)。相反,它是一種優秀的程式語言,適用於擁有所有 POSIX 綁定很有用的上下文(包括您想要呼叫其他 UNIX 應用程式的情況)。超過幾十行的shell腳本將總是無論你寫得多工整,都覺得自己像個駭客sh
;相比之下,沒有什麼可以阻止您使用 scsh 編寫重要的程式。
scsh 不是很緊湊(簡潔既是 sh 系列語言的優點也是缺點),但它很強大。
因為它對於小型和大型任務都很有用且實用,所以 scsh 順便說一下,它是掌握計劃的好方法(儘管,如果這恰好是您的目標,現在您最好直接使用 Racket)。
函數式語言的優勢不僅適用於列表密集型任務(儘管由於它們的歷史,它們傾向於將列表作為資料結構)——一旦你喝對了,它就是一種非常可靠的編寫程式的方法——援助。
sh 風格的 shell 是函數式的並沒有任何有意義的意義,而 Python 僅在它具有 lambda 函數的邊緣意義上是函數式的。