機能的なUnixシェルはありますか?


18

私は(本当に)関数型プログラミングの初心者です(実際にはPythonを使用してのみ関数型プログラミングと接触していました)が、シェル環境でのリスト集約型のタスクには良いアプローチのようです。

私はこのようなことをしたいです:

$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]

この種の機能を持つUnixシェルはありますか?または、Python内から簡単なシェルアクセス(コマンド、env / vars、readlineなど)を許可する機能があるかもしれません(bashの代わりにpythonのインタラクティブインタープリターを使用することです)。

編集:

たぶん比較例が明らかになるでしょう。dir / fileで構成されるリストがあるとしましょう:

$ FILES=( build/project.rpm build/project.src.rpm )

そして、私は本当に簡単なタスクをしたい:すべてのファイルをdist /にコピーし、それをシステムにインストールします(ビルドプロセスの一部です):

bashの使用:

$ cp $ {files [*]} dist /
$ cd dist && rpm -Uvh $($ {files [*]}のfの場合、do basename $ f; done))

「pythonic shell」アプローチの使用(注意:これは架空のコードです):

$ cp [FILES内のファイルのos.path.join( 'dist'、os.path.basename(file))] 'dist'

違いがわかりますか?それが私が話していることです。これらの種類のビルドインでシェルをまだ終了できないのはなぜですか?ファイルのリスト、PIDのリスト、すべてのリストなど、非常に一般的なタスクであっても、シェルでリストを処理するのは非常に苦痛です。

そして、本当に、本当に、重要なポイント:誰もが既に知っている構文/ツール/機能を使用する:shとpython。

IPythonは良い方向にあるように見えますが、肥大化しています。変数名が「$」で始まる場合はこれを行い、「$$」であればそれを行います。構文は「自然」ではないため、多くのルールと「回避策」([ ln.upper() for ln in !ls ] ->構文エラー)




4
関数型プログラミングには、リストの理解以上のものがあります。あなたの主な焦点が機能的なコードの作成である場合、私はPythonを例として取り上げません。
pqnet 14

回答:


10

おそらくあなたが探しているものに非常に近いスキームシェルがあります。私は自分で使ったことはありません。

更新:

私は自分でインストールして試してみました。scshは、本当に便利なインタラクティブシェルというよりも、インタラクティブなSchemeインタープリターおよびスクリプト言語のようです。ただタイプすることはできません

echo hello

構文は

(run (echo hello))

それを見つけるためにグーグルで数分かかりました。最初の例ここでは、次のとおりです。

gunzip < paper.tex.gz | detex | spell | lpr -Ppulp &

次のように変換されます:

(& (| (gunzip) (detex) (spell) (lpr -Ppulp)) (< paper.tex.gz))

ただし、単純なシェルコマンドの実行方法はわかりません。

このFAQエントリには次のように書かれています。

4.6 scshを対話型シェルとして使用できますか?

技術的には次のことができます。「scsh」コマンドを実行するだけで、すべてのscsh機能が利用可能なScheme 48セッションに入ります。ただし、これは間違いなくインタラクティブな作業には適していません。コマンドライン編集、コマンドライン履歴、ファイル/関数名の補完、簡潔な構文などはありません。

これらの問題を軽減するために、Martin GasbichlerとEric KnauelはCommander Sを作成しました。これはscshの上で実行され、快適なインタラクティブ環境を提供します。その斬新な機能の1つは、多くのUnixコマンドの出力を理解でき、ユーザーが有用な方法でそれを参照および操作できることです。:司令Sの詳細については、それを記述した論文に記載されています http://www.deinprogramm.de/scheme-2005/05-knauel/05-knauel.pdf 司令Sを入手してインストールする方法については、からご利用いただけますscsh Webサイト:http ://www.scsh.net/resources/commander-s.html

それが本当の答えかもしれません。


7

質問に直接回答するカテゴリには、BashやZshなどの機能的な代替として意図されているESシェルがあります。

次に、より機能的な標準シェルの作成を支援するカテゴリで、パイプミル技術の学習を検討します。

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(ループから出てくるnull以外の値のみを渡します)、2番目はeach(副作用のみのマップ)です。

これは、シェルでのfpの大幅な向上です。

シェルでより多くのfpスタイルで多くのことを表現することは可能ですが、それは思ったほど簡単ではありません。私たち全員がシェルをそんなにたくさん使用しているにもかかわらず、より良いシェルを作ることにあまり関心がないようです。


6

標準のBourneスタイルのシェル(shbashksh、など)、すでにあなたがしてみましょう:

for repo in repo1 repo2 repo3 ; do git clone $host/$repo ; done

doとの前にセミコロンが必要であることに注意してくださいdone。)また、bash他のシェルで$repoは、コマンドに一度しか表示されない場合、次のように記述できます。

git clone $host/{repo1,repo2,repo3}

確かに、私はそれをよく使います。しかし、ラムダ関数のような他のものはどうですか?

8
git clone $host/{repo1,repo2,repo3}forループと同じことはしません。git clone3つの引数で1回呼び出します。本質的に同じことを行うという事実は、どのようにgit clone機能するかという成果物です。他のコマンドには必ずしも適用されません。(たとえば、と比較echo foo bar bazしてくださいecho foo; echo bar; echo baz。)
キーストンプソン

使用FUN=eval 'git clone '"$host"'$0 するラムダを定義するために使用できる@carucciofor repo in repo{1,2,3} ; do $FUN $repo ; done
pqnet 14

最大の問題は、Unixツールに多くの副作用(ファイルへの書き込みなど)があるため、関数型言語で行いたいように作成できないことが多いことです。
weberc2

2

Scheme Shell、scshは本当に優れています。

キース・トンプソンが指摘しているように、インタラクティブなシェルとしては役に立ちません(コマンダーSは興味深い実験のように見えますが)。代わりに、すべてのPOSIXバインディングを使用すると便利なコンテキスト向けの優れたプログラミング言語です。これには、他のUNIXアプリケーションを呼び出す場合も含まれます。数十行以上のシェルスクリプトは、どんなにきちんと書いても、常にハックのように感じますsh。対照的に、scshを使用して重要なプログラムを作成するのを妨げるものは何もありません。

scshは非常にコンパクトではありません(簡潔さはshファミリ言語の長所と短所の両方です)が、強力です。

scshは、小規模および大規模なタスクに役立つ実用的であるため、偶然にもSchemeを理解するための良い方法です(ただし、それがたまたまあなたの目標であった場合は、最近、ラケットに直行することもできます)。

関数型言語の利点は、リストを集中的に使用するタスクだけではありません(ただし、その歴史のために、データ構造としてリストを優先する傾向があります)-適切なkoolを飲むと、プログラムを作成する非常に堅牢な方法です-援助。

shスタイルのシェルが機能する意味のある意味はありません。Pythonは、ラムダ関数を持っているというわずかな意味でのみ機能します。


2

シェルは必然的に非常に表情豊かです。つまり、より少ないライン、トークンなどで多くのことを達成できます。

通常、シェルやR、メイプルなどのDSLなど、特別な目的のために言語を設計することにより、言語を表現力豊かにします。

Python、Perl、Rubyなどは、シェル、ala duckタイピングに似た方法でより表現力のある汎用言語です。ALA、それらへのDSL GET溶接だからセージ数学のために。ただし、実際のシェルコマンドにはあまり適していません

Schemeは、すべての括弧が原因で、たとえDLSを構築したとしても、表現力豊かではありません。

しかし、非常に表現力が高く、DSLを構築する能力の高いHaskellのような機能言語があります。Haskellでシェルを構築する興味深い努力は、シェリーです。

実際には、Haskellの強力だが制限的な型システムによる努力ツールを備えた学習曲線がありますが、かなりの見込みがあります。


1

まず、"${files[@]}"どこでも使用する必要があります${files[*]}。そうしないと、スペースが混乱します。

シェルはすでにかなり機能しています。テキスト出力が行のリストであると考える場合、grepis filterxargsis mapなどです。パイプは非常に機能的です。

シェルは明らかに友好的なプログラミング環境ではありませんが、Pythonよりもインタラクティブな使用により適しています。また、APIとUIが同一であるという非常に優れた機能を備えています。両方を一度に学習してください。

あなたがなぜcp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist'望ましいのか分かりませんcp "${FILES[@]}" dist。後者は入力がはるかに少ないです。


0

それが「機能的」であることを知らないが、scshの論文で言及されているrcもあります。esの前身です。

Linux Mint(およびおそらくDebian、Ubuntu ...)では、

sudo apt-get install rc
man rc
rc
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.