Saya (benar-benar) pemula untuk pemrograman fungsional (pada kenyataannya hanya bersentuhan dengannya menggunakan python) tetapi tampaknya menjadi pendekatan yang baik untuk beberapa tugas intensif dalam lingkungan shell.
Saya ingin melakukan sesuatu seperti ini:
$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]
Apakah ada shell Unix dengan fitur semacam ini? Atau mungkin beberapa fitur untuk memungkinkan akses shell yang mudah (perintah, env / vars, readline, dll ...) dari dalam python (idenya adalah menggunakan interpreter interaktif python sebagai pengganti bash).
SUNTING:
Mungkin contoh komparatif akan menjelaskan. Katakanlah saya memiliki daftar yang terdiri dari dir / file :
$ FILES=( build/project.rpm build/project.src.rpm )
Dan saya ingin melakukan tugas yang sangat sederhana: salin semua file ke dist / DAN instal di sistem (itu bagian dari proses build):
Menggunakan bash:
$ cp $ {files [*]} dist / $ cd dist && rpm -Uvh $ (untuk f di $ {file [*]}; lakukan basename $ f; selesai))
Menggunakan pendekatan "pythonic shell" (hati-hati: ini adalah kode imajiner):
$ cp [os.path.join ('dist', os.path.basename (file)) untuk file dalam FILES] 'dist'
Bisakah Anda melihat perbedaannya? ITULAH yang saya bicarakan. Bagaimana tidak bisa keluar dari shell dengan hal-hal semacam ini? Ini sangat menyusahkan untuk menangani daftar dalam shell, bahkan itu menjadi tugas yang sangat umum: daftar file, daftar PID, daftar segalanya.
Dan poin yang sangat, sangat, penting: menggunakan sintaks / alat / fitur yang semua orang sudah tahu: sh dan python.
IPython tampaknya berada di arah yang baik, tetapi itu membengkak: jika nama var dimulai dengan '$', itu melakukan ini, jika '$$' itu melakukan itu. Sintaksnya bukan "alami", begitu banyak aturan dan "pemecahan masalah" ( [ ln.upper() for ln in !ls ]
-> kesalahan sintaksis)
Jawaban:
Ada Skema Shell yang mungkin sangat dekat dengan apa yang Anda cari. Saya belum menggunakannya sendiri.
PEMBARUAN:
Saya baru saja menginstal dan mencobanya sendiri. Tampaknya scsh lebih merupakan juru bahasa Skema interaktif dan bahasa skrip daripada shell interaktif yang sangat berguna. Anda tidak bisa mengetik begitu saja
sintaks tampaknya
dan butuh beberapa menit dari Googling untuk menemukannya. Contoh pertama di sini adalah:
yang diterjemahkan menjadi:
tapi itu tidak memberi tahu Anda cara menjalankan perintah shell sederhana .
Entri FAQ ini mengatakan:
Jadi mungkin itulah jawaban sebenarnya.
sumber
Standar Bourne-gaya kerang (
sh
,bash
,ksh
, dll) sudah membiarkan Anda lakukan:(Perhatikan perlunya titik koma sebelum
do
dandone
.) Selain itu, dalambash
dan shell lainnya, jika$repo
hanya muncul sekali dalam perintah, Anda dapat menulis:sumber
git clone $host/{repo1,repo2,repo3}
tidak melakukan hal yang sama denganfor
loop; itu memanggilgit clone
sekali dengan tiga argumen. Fakta yang pada dasarnya melakukan hal yang sama adalah artefak tentang caragit clone
kerjanya; itu tidak selalu berlaku untuk perintah lain. (Bandingkanecho foo bar baz
denganecho foo; echo bar; echo baz
, misalnya.)FUN=eval 'git clone '"$host"'$0
untuk mendefinisikan lambda untuk digunakan sebagaifor repo in repo{1,2,3} ; do $FUN $repo ; done
Dalam kategori menjawab pertanyaan secara langsung, ada shell ES yang dimaksudkan sebagai pengganti fungsional untuk Bash dan Zsh dll.
Kedua, dalam kategori membantu Anda menulis lebih banyak shell standar fungsional, pertimbangkan mempelajari teknik pipemill:
Loop sementara pertama adalah fungsional
keep
(hanya meneruskan nilai-nilai non-null yang keluar dari loop) dan yang kedua adalaheach
(peta untuk efek samping saja).Ini adalah dorongan luar biasa untuk fp di kulit.
Dimungkinkan untuk mengekspresikan banyak hal dalam gaya yang lebih fp dalam sebuah shell, hanya saja tidak semudah itu. Tampaknya tidak banyak minat untuk membuat cangkang yang lebih baik, meskipun kita semua sering menggunakannya.
sumber
Skema Shell, scsh, sangat bagus.
Seperti dicatat Keith Thompson, itu tidak berguna sebagai shell interaktif (meskipun Komandan S terlihat seperti percobaan yang menarik). Alih-alih, ini adalah bahasa pemrograman yang sangat baik untuk konteks di mana memiliki semua ikatan POSIX berguna - yang mencakup kasus di mana Anda ingin memanggil aplikasi unix lainnya. Sebuah skrip shell dengan lebih dari beberapa lusin baris akan selalu terasa seperti retasan, tidak peduli seberapa rapi Anda menulis
sh
; Sebaliknya tidak ada yang menghentikan Anda menulis program signifikan menggunakan scsh.scsh tidak terlalu kompak (singkatnya adalah kekuatan dan kelemahan bahasa sh-family), tapi itu kuat.
Karena ini berguna dan praktis untuk tugas-tugas kecil dan besar, scsh secara kebetulan merupakan cara yang baik untuk menguasai Skema (walaupun, jika itu adalah tujuan Anda, Anda mungkin akan langsung pergi ke Racket, hari ini).
Keuntungan dari bahasa fungsional bukan hanya untuk tugas-tugas yang intensif daftar (meskipun karena sejarahnya, mereka cenderung memilih daftar sebagai struktur data) - ini adalah cara yang sangat kuat untuk membuat program ditulis, setelah Anda meminum kool yang tepat. membantu.
Tidak ada arti yang berarti di mana kerang sh-style berfungsi, dan Python hanya berfungsi dalam arti marginal bahwa ia memiliki fungsi lambda.
sumber
Kerang tentu sangat ekspresif, artinya Anda mencapai banyak dengan garis, token, dll yang lebih sedikit.
Kami biasanya membuat bahasa ekspresif dengan mendesainnya untuk tujuan khusus, seperti cangkang atau DSL seperti R, maple, dll. Dan Anda menemukan ekspresif yang relatif sedikit dalam sebagian besar bahasa tujuan umum seperti C, C ++, Java, dll.
Python, Perl, Ruby, dll. Adalah bahasa tujuan umum yang lebih ekspresif dengan cara yang mirip dengan kerang, mengetik ala bebek. Jadi DSLs dilas ke mereka, ala Sage untuk matematika. Tidak begitu bagus untuk perintah shell yang sebenarnya .
Skema tidak imho yang ekspresif, bahkan setelah Anda membangun DLS, karena semua tanda kurung.
Namun ada bahasa fungsional seperti Haskell dengan ekspresi yang sangat besar dan kapasitas yang besar untuk membangun DSL. Upaya menarik untuk membangun shell di Haskell adalah kura - kura dan shelly .
Dalam praktiknya, ada kurva belajar dengan alat upaya karena Haskell sistem tipe kuat tapi membatasi, tetapi mereka menunjukkan janji yang cukup besar.
sumber
Pertama, Anda harus menggunakan
"${files[@]}"
semua yang Anda miliki${files[*]}
. Jika tidak, spasi akan mengacaukan Anda.Shell sudah cukup fungsional; jika Anda berpikir dalam hal output teks menjadi daftar baris, maka
grep
adalahfilter
,xargs
adalahmap
, dll. Pipa sangat fungsional.Shell diakui bukan lingkungan pemrograman yang ramah, tetapi jauh lebih cocok untuk penggunaan interaktif daripada Python. Dan ia memiliki fitur yang sangat bagus bahwa API dan UI identik - pelajari keduanya sekaligus.
Saya tidak mengerti mengapa Anda merasa
cp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist'
lebih disukaicp "${FILES[@]}" dist
. Yang terakhir jauh lebih sedikit mengetik.sumber
Tidak tahu itu menjadi "fungsional", tetapi ada juga rc , yang disebutkan dalam makalah scsh . Ini adalah predecesor untuk es.
Di Linux Mint (dan mungkin Debian, Ubuntu ...) Anda dapat mencobanya
sumber