Diese Seite hatte viele Probleme mit der Implementierung verschiedener Sprachen in Interpreter- Tags. Praktisch alle waren esoterische Sprachen, die niemand benutzte. Es ist Zeit, einen Dolmetscher für eine praktische Sprache zu entwickeln, die die meisten Benutzer hier wahrscheinlich bereits kennen. Ja, es ist ein Shell-Skript, falls Sie Probleme haben, den Titel zu lesen (nicht das, was Sie haben). (Ja, ich habe diese Herausforderung absichtlich gemeistert, da es mir langweilig ist, dass Sprachen wie GolfScript und Befunge alles gewinnen. Deshalb habe ich einige Herausforderungen gestellt, bei denen eine praktischere Programmiersprache größere Gewinnchancen hat.)
Da das Shell-Skript jedoch eine relativ große Sprache ist, werde ich Sie nicht bitten, es zu implementieren. Stattdessen werde ich einen kleinen Teil der Shell-Skriptfunktionalität erstellen.
Die Untergruppe, für die ich mich entschieden habe, ist die folgende Untergruppe:
- Ausführen von Programmen (Programme enthalten jedoch nur Buchstaben, auch wenn einfache Anführungszeichen zulässig sind)
- Programmargumente
- Einfache Anführungszeichen (akzeptieren alle druckbaren ASCII-Zeichen, einschließlich Leerzeichen, ohne einfache Anführungszeichen)
- Zeichenfolgen ohne Anführungszeichen (ASCII-Buchstaben, -Zahlen und -Bindestriche sind zulässig)
- Rohre
- Leere Anweisungen
- Mehrere Anweisungen durch eine neue Zeile getrennt
- Nachgestellte / führende / mehrere Leerzeichen
In dieser Task müssen Sie die Eingabe von STDIN lesen und jeden angeforderten Befehl ausführen. Sie können mit Sicherheit von einem POSIX-kompatiblen Betriebssystem ausgehen, sodass keine Portabilität mit Windows oder Ähnlichem erforderlich ist. Sie können davon ausgehen, dass die Programme, die nicht an andere Programme weitergeleitet werden, nicht aus STDIN lesen. Sie können davon ausgehen, dass die Befehle vorhanden sein werden. Sie können davon ausgehen, dass nichts anderes verwendet wird. Wenn eine sichere Annahme gebrochen ist, können Sie alles tun. Sie können sicher annehmen, dass höchstens 15 Argumente und Zeilen mit weniger als 512 Zeichen vorhanden sind (wenn Sie eine explizite Speicherzuweisung benötigen oder so etwas - ich werde wirklich kleine Gewinnchancen für C geben, auch wenn diese noch klein sind). Sie müssen keine Dateideskriptoren bereinigen.
Sie können Programme jederzeit ausführen - auch nach Erhalt der vollständigen Zeile oder nach Beendigung von STDIN. Wählen Sie einen beliebigen Ansatz.
Einfacher Testfall, mit dem Sie Ihre Shell testen können (beachten Sie das Leerzeichen nach dem dritten Befehl):
echo hello world
printf '%08X\n' 1234567890
'echo' 'Hello, world!'
echo heeeeeeelllo | sed 's/\(.\)\1\+/\1/g'
yes|head -3
echo '\\'
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
Das obige Programm sollte folgendes Ergebnis ausgeben:
hello world
499602D2
Hello, world!
helo
y
y
y
\\
foo BAR zap
Sie dürfen die Shell nicht selbst ausführen, es sei denn, Sie haben keine Argumente für den Befehl (diese Ausnahme wurde für Perl gemacht, das den Befehl in der Shell ausführt, wenn nur ein Argument eingegeben wird system
, aber Sie können diese Ausnahme für andere missbrauchen auch Sprachen, wenn Sie dies auf eine Weise tun können, die Zeichen spart), oder der Befehl, den Sie ausführen, ist die Shell selbst. Dies ist wahrscheinlich das größte Problem bei dieser Herausforderung, da viele Sprachen system
Funktionen haben, die Shell ausführen. Verwenden Sie stattdessen Sprach-APIs, die Programme direkt aufrufen, z. B. subprocess
Module in Python. Dies ist ohnehin eine gute Idee für die Sicherheit, und Sie möchten keine unsichere Shell erstellen, oder? Dies stoppt höchstwahrscheinlich PHP, aber es gibt trotzdem andere Sprachen zur Auswahl.
Wenn Sie vorhaben , Ihr Programm in Shell - Skript zu machen, sind Sie nicht verwenden dürfen eval
, source
oder .
(wie in, eine Funktion, kein Zeichen). Das würde meiner Meinung nach die Herausforderung zu einfach machen.
Cleverer Regelmissbrauch erlaubt. Es gibt viele Dinge, die ich ausdrücklich untersagt habe, aber ich bin mir fast sicher, dass Sie immer noch Dinge tun dürfen, an die ich nicht gedacht habe. Manchmal wundert es mich, wie Leute meine Regeln interpretieren. Denken Sie auch daran, dass Sie alles für alles tun können, was ich nicht erwähnt habe. Wenn ich zum Beispiel versuche, Variablen zu verwenden, können Sie die Festplatte löschen (aber bitte nicht).
Der kürzeste Code gewinnt, da dies Codegolf ist.
quelle
Antworten:
Bash (92 Bytes)
Nutzen Sie die gleiche Lücke wie diese Antwort , um eine viel kürzere Lösung zu finden:
Python (
247241239 Byte)quelle
*
), aber ansonsten sieht es großartig aus :-). Ich bin überrascht, dass ein neues Mitglied eine so gute Lösung für ein schwieriges Problem gefunden hat.C (340 Bytes)
Ich habe überhaupt keine Erfahrung im Golfen, aber Sie müssen irgendwo anfangen, also hier geht's:
Ich habe Zeilenumbrüche hinzugefügt, damit Sie nicht scrollen müssen, habe sie aber nicht in meine Zählung aufgenommen, da sie keine semantische Bedeutung haben. Die nach Präprozessor-Direktiven sind erforderlich und wurden gezählt.
Ungolfed-Version
Eigenschaften
'ec'ho He'll''o 'world
arbeiten, wie sie sollen. Könnte gut sein, dass der Code ohne diese Funktion einfacher gewesen wäre, daher würde ich eine Klarstellung begrüßen, ob dies erforderlich ist.Bekannte Probleme
execvp
Aufruf fehlschlägt, z. B. aufgrund eines falsch eingegebenen Programmnamens. Dann spielen zwei Prozesse gleichzeitig die Rolle der Muschel.Sonderzeichen '|' und Zeilenumbruch behalten ihre besondere Bedeutung innerhalb der in Anführungszeichen gesetzten Zeichenfolgen. Dies verstößt gegen die Anforderungen, daher suche ich nach Möglichkeiten, dies zu beheben.Behoben, bei einem Aufwand von ca. 11 Bytes.Weitere Hinweise
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
es hängen blieb. Das Problem war anscheinend die nicht geschlossene Write-Pipe, daher musste ich den Befehl close hinzufügen, der meine Codegröße um 10 Byte erhöhte. Möglicherweise gibt es Systeme, in denen diese Situation nicht auftritt, sodass mein Code möglicherweise mit 10 Byte weniger bewertet wird. Ich weiß es nicht.?:
geschachtelt haben kann .,
(…)
quelle
int c, m, f[3];
draußen gehenmain
, um das Deklarieren von Typen zu vermeiden. Für globale Variablen müssen Sie nicht deklarierenint
. Aber im Allgemeinen interessante Lösung.yes|head -3
bleiben für immer bestehen, und die Shell wird nach jedem einzelnen Befehl beendet. Ich verwende die gcc-Version 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu5) ohne Schalter.#define B break;case
(dasbreak;
Vorherdefault
wird)B-1:
) und 2 durch Ersetzen voncase'\n'
undcase'\''
durchcase 10
undcase 39
.Bash (+ Bildschirm) 160
Gibt etwas aus wie:
quelle
Faktor (208 Zeichen)
Da die Regeln das Auslagern der Arbeit an Dritte ( http://www.compileonline.com/execute_bash_online.php ) nicht verbieten , gibt es hier eine Lösung:
Sie können das Programm auch als noch kürzeren Einzeiler in die Antwort schreiben ( 201 Zeichen):
quelle
Perl, 135 Zeichen
Diese Shell macht einige dumme Sachen. Starten Sie eine interaktive Shell mit
perl shell.pl
und probieren Sie es aus:ls
Druckt in einer Spalte, da die Standardausgabe kein Terminal ist. Die Shell leitet die Standardausgabe an eine Pipe um und liest aus der Pipe.perl -E 'say "hi"; sleep 1'
Wartet 1 Sekunde, um Hallo zu sagen, da die Shell die Ausgabe verzögert.dd
Liest 0 Bytes, es sei denn, es ist der erste Befehl für diese Shell. Die Shell leitet die Standardeingabe von einer leeren Pipe für jede Pipeline nach der ersten Pipe um.perl -e '$0 = screamer; print "A" x 1000000' | dd of=/dev/null
erfolgreich abgeschlossen.perl -e '$0 = screamer; print "A" x 1000000' | cat | dd of=/dev/null
hängt die Muschel!pkill -f screamer
anderen Shell), wird die Shell fortgesetzt.perl -e 'fork and exit; $0 = sleeper; sleep'
hängt die Muschel!'echo $((2+3))'
Führt den Befehl in / bin / sh aus. Dies ist das Verhalten von Perls exec und system mit einem Argument, jedoch nur, wenn das Argument Sonderzeichen enthält.Ungolfed-Version
quelle