Gibt es eine funktionale Unix-Shell?

Gibt es eine funktionale Unix-Shell?

Ich bin (wirklich) ein Neuling in der funktionalen Programmierung (hatte eigentlich nur Kontakt damit über Python), aber es scheint ein guter Ansatz für einige listenintensive Aufgaben in einer Shell-Umgebung zu sein.

Ich würde gerne so etwas machen:

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

Gibt es eine Unix-Shell mit dieser Art von Funktion? Oder vielleicht eine Funktion, die einen einfachen Shell-Zugriff (Befehle, Umgebung/Variablen, Readline usw.) aus Python heraus ermöglicht (die Idee ist, den interaktiven Interpreter von Python als Ersatz für Bash zu verwenden).

BEARBEITEN:

Vielleicht würde ein Vergleichsbeispiel Klarheit schaffen. Nehmen wir an, ich habe eine Liste bestehend ausVerzeichnis/Datei:

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

Und ich möchte eine wirklich einfache Aufgabe erledigen: alle Dateien kopieren nachEntfernung/UND installieren Sie es im System (es ist Teil eines Build-Prozesses):

Mit Bash:

$ cp ${Dateien[*]} dist/
$ cd dist && rpm -Uvh $(für f in ${files[*]}; mache Basisname $f; fertig))

Verwenden eines „Pythonic Shell“-Ansatzes (Achtung: Dies ist imaginärer Code):

$ cp [ os.path.join('dist', os.path.basename(file)) für Datei in DATEIEN ] 'dist'

Sehen Sie den Unterschied? DAS ist es, wovon ich spreche. Wie kann man eine Shell nicht beenden, wenn diese Art von Sachen schon eingebaut ist? Es ist wirklich mühsam, Listen in der Shell zu handhaben, obwohl es eine so häufige Aufgabe ist: Liste von Dateien, Liste von PIDs, Liste von allem.

Und ein wirklich, wirklich wichtiger Punkt: Verwenden Sie Syntax/Tools/Funktionen, die jeder bereits kennt: sh und Python.

IPython scheint in eine gute Richtung zu gehen, ist aber aufgebläht: Wenn der Variablenname mit '$' beginnt, macht es dies, wenn '$$', macht es das. Seine Syntax ist nicht „natürlich“, so viele Regeln und „Workarounds“ ( [ ln.upper() for ln in !ls ] --> Syntaxfehler)

Antwort1

Da ist einSchema-Shelldas kommt wahrscheinlich dem sehr nahe, was Sie suchen. Ich habe es selbst nicht verwendet.

AKTUALISIEREN :

Ich habe es gerade selbst installiert und ausprobiert. Es scheint, dass scsh eher ein interaktiver Scheme-Interpreter und eine Skriptsprache als eine wirklich nützliche interaktive Shell ist. Sie können nicht einfach Folgendes eingeben:

echo hello

die Syntax scheint zu sein

(run (echo hello))

und es dauerte mehrere Minuten, bis ich das herausfand. Das erste BeispielHierIst:

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

was übersetzt bedeutet:

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

aber das sagt Ihnen nicht, wie man eineinfachShell-Befehl.

Dieser FAQ-Eintragsagt:

4.6 Kann ich scsh als interaktive Shell verwenden?

Nun, technisch gesehen ist das möglich: Führen Sie einfach den Befehl „scsh“ aus und Sie gelangen in eine Scheme 48-Sitzung mit allen verfügbaren scsh-Funktionen. Dies ist jedoch definitiv nicht für interaktives Arbeiten geeignet: Es gibt keine Befehlszeilenbearbeitung, keinen Befehlszeilenverlauf, keine Vervollständigung von Datei-/Funktionsnamen, keine knappe Syntax usw.

Um diese Probleme zu beheben, haben Martin Gasbichler und Eric Knauel Commander S geschrieben, das auf scsh läuft und eine komfortable interaktive Umgebung bietet. Eine seiner neuen Funktionen ist, dass es die Ausgabe vieler Unix-Befehle verstehen kann und es dem Benutzer ermöglicht, sie auf nützliche Weise zu durchsuchen und zu bearbeiten. Weitere Informationen zu Commander S finden Sie in dem Dokument, das es beschreibt: http://www.deinprogramm.de/scheme-2005/05-knauel/05-knauel.pdf Anweisungen zum Bezug und zur Installation von Commander S finden Sie auf der scsh-Website:http://www.scsh.net/resources/commander-s.html

Vielleicht ist das die wahre Antwort.

Antwort2

In der Kategorie der direkten Beantwortung der Frage gibt es dieES-Schaledas als funktionaler Ersatz für Bash und Zsh etc. gedacht ist.

Zweitens sollten Sie im Rahmen der Hilfestellung zum Schreiben funktionalerer Standard-Shells das Erlernen der Pipemill-Technik in Betracht ziehen:

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

Die erste While-Schleife ist eine Funktion keep(gibt nur die ungleich Null-Werte weiter, die aus der Schleife kommen) und die zweite ist eine each(Map nur für Nebeneffekte).

Dies ist eine enorme Steigerung der FP in Shells.

Es ist möglich, viele Dinge in einer Shell in einem eher fp-artigen Stil auszudrücken, es ist nur nicht so einfach, wie es sein könnte. Es scheint, dass kein großes Interesse daran besteht, bessere Shells zu erstellen, obwohl wir sie alle so häufig verwenden.

Antwort3

Mit den Standard-Shells im Bourne-Stil ( sh, bash, ksh, usw.) können Sie bereits Folgendes tun:

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

(Beachten Sie, dass vor dound ein Semikolon stehen muss done.) Darüber hinaus können Sie in bashund anderen Shells, wenn $repo„nur einmal“ im Befehl vorkommt, Folgendes schreiben:

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

Antwort4

Scheme Shell, scsh, ist wirklich gut.

Wie Keith Thompson bemerkt, ist es nicht als interaktive Shell geeignet (obwohl Commander S wie ein interessantes Experiment aussieht). Stattdessen ist es eine ausgezeichnete Programmiersprache für Kontexte, in denen es nützlich ist, alle POSIX-Bindungen zu haben – das schließt Fälle ein, in denen Sie andere Unix-Anwendungen aufrufen möchten. Ein Shell-Skript mit mehr als ein paar Dutzend Zeilen wirdstetsSie werden sich wie ein Stümper vorkommen, egal, wie ordentlich Sie schreiben sh; im Gegensatz dazu hindert Sie nichts daran, mit scsh bedeutende Programme zu schreiben.

scsh ist nicht sehr kompakt (Kürze ist sowohl die Stärke als auch die Schwäche der Sprachen der sh-Familie), aber es ist leistungsstark.

Da es für kleine und große Aufgaben nützlich und praktisch ist, ist scsh im Übrigen eine gute Möglichkeit, sich mit einem Scheme vertraut zu machen (obwohl Sie heutzutage, wenn dies zufällig Ihr Ziel ist, genauso gut gleich zu Racket wechseln können).

Die Vorteile funktionaler Sprachen liegen nicht nur bei listenintensiven Aufgaben (obwohl sie aufgrund ihrer Geschichte Listen als Datenstruktur bevorzugen) – wenn man die richtige Portion Mut zu sich nimmt, ist dies eine wirklich robuste Methode zum Schreiben von Programmen.

Es gibt keinen sinnvollen Sinn, in dem die Shells im sh-Stil funktional wären, und Python ist nur in dem marginalen Sinn funktional, dass es eine Lambda-Funktion hat.

verwandte Informationen