Ta strona miała wiele problemów związanych z implementacją różnych języków w tagu tłumacza . Jednak praktycznie wszystkie z nich były językami ezoterycznymi, których nikt nie używa. Czas na tłumacza praktycznego języka, który prawdopodobnie zna już większość użytkowników. Tak, to skrypt powłoki na wypadek problemów z odczytaniem tytułu (nie że tak). (tak, celowo podjąłem to wyzwanie, ponieważ nudzę się takimi językami jak GolfScript i Befunge, które wygrywają wszystko, więc stawiam wyzwanie, gdy bardziej praktyczny język programowania ma większe szanse na wygraną)
Jednak skrypt powłoki jest stosunkowo dużym językiem, więc nie będę prosił o jego implementację. Zamiast tego stworzę mały podzbiór funkcji skryptu powłoki.
Podzbiór, który zdecydowałem, to następujący podzbiór:
- Wykonywanie programów (programy będą zawierać tylko litery, nawet jeśli dozwolone są pojedyncze cudzysłowy)
- Argumenty programowe
- Pojedyncze cudzysłowy (akceptujący dowolny znak ASCII do wydruku, w tym spacje, z wyłączeniem pojedynczego cudzysłowu)
- Niecytowane ciągi znaków (zezwalające na litery, cyfry i myślniki ASCII)
- Rury
- Puste wyciągi
- Wiele instrukcji oddzielonych nowym wierszem
- Spacje końcowe / wiodące / wiele spacji
W tym zadaniu musisz odczytać dane wejściowe ze STDIN i uruchomić każdą żądaną komendę. Możesz bezpiecznie założyć system operacyjny zgodny z POSIX, więc nie ma potrzeby przenośności z Windows, ani nic podobnego. Możesz bezpiecznie założyć, że programy, które nie są potokowane do innych programów, nie będą czytać ze STDIN. Możesz bezpiecznie założyć, że polecenia będą istnieć. Możesz bezpiecznie założyć, że nic więcej nie zostanie użyte. Jeśli jakieś bezpieczne założenie zostanie złamane, możesz zrobić wszystko. Możesz bezpiecznie założyć maksymalnie 15 argumentów i wiersze poniżej 512 znaków (jeśli potrzebujesz jawnego przydziału pamięci lub coś takiego - naprawdę dam małe szanse na wygraną dla C, nawet jeśli nadal są małe). Nie musisz czyścić deskryptorów plików.
Możesz wykonywać programy w dowolnym momencie - nawet po otrzymaniu pełnej linii lub po zakończeniu STDIN. Wybierz dowolne podejście.
Prosta walizka testowa, która pozwala przetestować powłokę (zwróć uwagę na końcowe białe znaki po trzecim poleceniu):
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/'
Powyższy program powinien wypisać następujący wynik:
hello world
499602D2
Hello, world!
helo
y
y
y
\\
foo BAR zap
Nie możesz wykonać samej powłoki, chyba że nie masz żadnych argumentów dla polecenia (ten wyjątek został stworzony dla Perla, który uruchamia polecenie w powłoce po umieszczeniu tylko argumentu system
, ale możesz nadużywać tego wyjątku dla innych języki, jeśli możesz to zrobić w sposób, który oszczędza znaki), lub uruchomione polecenie jest samą powłoką. Jest to prawdopodobnie największy problem w tym wyzwaniu, ponieważ wiele języków ma system
funkcje wykonujące powłokę. Zamiast tego używaj interfejsów API języka, które wywołują programy bezpośrednio, takich jak subprocess
moduł w Pythonie. To i tak jest dobry pomysł na bezpieczeństwo, a cóż, nie chciałbyś stworzyć niepewnej powłoki, prawda? To najprawdopodobniej zatrzymuje PHP, ale i tak można wybrać inne języki.
Jeśli masz zamiar zrobić swój program w skrypcie powłoki, nie wolno używać eval
, source
albo .
(jak w, funkcji, a nie znaków). Moim zdaniem wyzwanie byłoby zbyt łatwe.
Dopuszczalne sprytne nadużywanie reguł. Jest wiele rzeczy, których wyraźnie zabroniłem, ale jestem prawie pewien, że nadal możesz robić rzeczy, o których nie myślałem. Czasami jestem zaskoczony tym, jak ludzie interpretują moje zasady. Pamiętaj też, że możesz zrobić wszystko dla czegoś, o czym nie wspomniałem. Na przykład, jeśli spróbuję użyć zmiennych, możesz wyczyścić dysk twardy (ale nie rób tego).
Wygrywa najkrótszy kod, ponieważ jest to codegolf.
źródło
Odpowiedzi:
Bash (92 bajty)
Korzystając z tej samej luki co ta odpowiedź , oto znacznie krótsze rozwiązanie:
Python (
247241239 bajtów)źródło
*
), ale poza tym wygląda świetnie :-). Dziwi mnie, że nowy członek tak dobrze rozwiązał trudny problem.C (340 bajtów)
Nie mam żadnego doświadczenia w golfie, ale musisz gdzieś zacząć, więc oto:
Dodałem podział wiersza, abyś nie musiał przewijać, ale nie uwzględniłem ich w mojej liczbie, ponieważ nie mają one znaczenia semantycznego. Te po dyrektywach preprocesora są wymagane i zostały policzone.
Wersja bez golfa
funkcje
'ec'ho He'll''o 'world
jak powinny działać tak, jak powinny. Być może kod byłby prostszy bez tej funkcji, dlatego z przyjemnością wyjaśnię, czy jest to wymagane.Znane problemy
execvp
wywołanie nie powiedzie się, np. Z powodu błędnie wpisanej nazwy programu. Następnie mamy dwa procesy grające jednocześnie w powłoki.Znaki specjalne „|” i łamanie linii zachowuje swoje specjalne znaczenie w cytowanych ciągach. Jest to niezgodne z wymogami, więc badam sposoby rozwiązania tego problemu.Naprawiono, kosztem około 11 bajtów.Inne notatki
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
się zawiesiłem. Problemem najwyraźniej był niezamknięty potok zapisu, więc musiałem dodać polecenie close, które zwiększyło mój kod o 10 bajtów. Być może istnieją systemy, w których taka sytuacja nie występuje, więc mój kod może zostać oceniony z 10 bajtami mniej. Nie wiem?:
może mieć zagnieżdżone,
bez(…)
.źródło
int c, m, f[3];
zewnątrzmain
, aby uniknąć deklarowania typów. W przypadku zmiennych globalnych nie musisz deklarowaćint
. Ale ogólnie ciekawe rozwiązanie.yes|head -3
wiecznie, a powłoka wychodzi po każdym poleceniu. Używam gcc w wersji 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu5) bez żadnych przełączników.#define B break;case
(break;
wcześniejdefault
staje się)B-1:
) i 2, zastępująccase'\n'
icase'\''
) przezcase 10
icase 39
.bash (+ ekran) 160
Wyprowadzi coś takiego:
źródło
Współczynnik (208 znaków)
Ponieważ reguły nie zabraniają przekazywania pracy osobom trzecim ( http://www.compileonline.com/execute_bash_online.php ), oto rozwiązanie:
Możesz napisać program jako jeszcze krótszy jeden wiersz w replice ( 201 znaków):
źródło
Perl, 135 znaków
Ta skorupa robi głupie rzeczy. Uruchom interaktywną powłokę za pomocą
perl shell.pl
i spróbuj:ls
wypisuje w jednej kolumnie, ponieważ standardowe wyjście nie jest terminalem. Powłoka przekierowuje standardowe wyjście do potoku i odczytuje z potoku.perl -E 'say "hi"; sleep 1'
czeka 1 sekundę na przywitanie, ponieważ powłoka opóźnia wyjście.dd
odczytuje 0 bajtów, chyba że jest to pierwsze polecenie tej powłoki. Powłoka przekierowuje standardowe wejście z pustej potoku dla każdego potoku po pierwszym.perl -e '$0 = screamer; print "A" x 1000000' | dd of=/dev/null
kończy się pomyślnie.perl -e '$0 = screamer; print "A" x 1000000' | cat | dd of=/dev/null
wisi muszla!pkill -f screamer
inną powłoką), to powłoka zostanie wznowiona.perl -e 'fork and exit; $0 = sleeper; sleep'
wisi muszla!'echo $((2+3))'
uruchamia polecenie w / bin / sh. Jest to zachowanie systemu wykonawczego i systemu Perla z jednym argumentem, ale tylko wtedy, gdy argument zawiera znaki specjalne.Wersja bez golfa
źródło