На этом сайте было много проблем, связанных с использованием различных языков в теге интерпретатора . Однако практически все они были эзотерическими языками, которые никто не использует. Время сделать переводчика для практического языка, который большинство пользователей здесь, вероятно, уже знают. Да, это сценарий оболочки, если у вас есть проблемы с чтением заголовка (не так, как у вас). (да, я специально сделал это, потому что мне надоели такие языки, как GolfScript и Befunge, которые выигрывают все, поэтому я поставил перед собой задачу, когда более практичный язык программирования имеет больше шансов на победу)
Однако сценарий оболочки является относительно большим языком, поэтому я не буду просить вас его реализовать. Вместо этого я собираюсь сделать небольшое подмножество функций сценариев оболочки.
Подмножество, которое я выбрал, является следующим:
- Выполнение программ (однако, программы будут содержать только буквы, даже если допускаются одинарные кавычки)
- Программные аргументы
- Одинарные кавычки (допускаются любые печатные символы ASCII, включая пробелы, за исключением одинарных кавычек)
- Строки без кавычек (допускаются буквы ASCII, цифры и тире)
- трубы
- Пустые выписки
- Несколько операторов, разделенных новой строкой
- Трейлинг / ведущий / несколько пробелов
В этой задаче вы должны прочитать входные данные из STDIN и выполнить каждую запрошенную команду. Вы можете смело полагаться на POSIX-совместимую операционную систему, поэтому нет необходимости в переносимости с Windows или чем-то подобным. Вы можете с уверенностью предположить, что программы, которые не передаются другим программам, не будут читать из STDIN. Вы можете смело предполагать, что команды будут существовать. Вы можете смело предполагать, что больше ничего не будет использовано. Если какое-то безопасное предположение нарушается, вы можете сделать что угодно. Вы можете смело предположить не более 15 аргументов и строки длиной менее 512 символов (если вам нужно явное распределение памяти или что-то в этом роде - я действительно собираюсь дать небольшие шансы на победу для C, даже если они все еще малы). Вам не нужно очищать файловые дескрипторы.
Вам разрешено выполнять программы в любой момент - даже после получения полной строки или после окончания STDIN. Выберите любой подход, который вы хотите.
Простой тестовый сценарий, который позволяет вам протестировать вашу оболочку (обратите внимание на пробельные символы после третьей команды):
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/'
Программа выше должна вывести следующий результат:
hello world
499602D2
Hello, world!
helo
y
y
y
\\
foo BAR zap
Вы не можете запускать саму оболочку, если у вас нет аргументов для команды (это исключение было сделано для Perl, который запускает команду в оболочке, когда вводит только аргумент system
, но не стесняйтесь использовать это исключение для других языки, если вы можете сделать это таким образом, чтобы сохранить символы), или команда, которую вы выполняете, это сама оболочка. Это, вероятно, самая большая проблема в этой задаче, так как многие языки имеют system
функции, выполняющие оболочку. Вместо этого используйте языковые API, которые вызывают программы напрямую, например, subprocess
модуль в Python. В любом случае, это хорошая идея для безопасности, и вы бы не хотели создавать небезопасную оболочку, не так ли? Скорее всего, это останавливает PHP, но в любом случае есть другие языки.
Если вы собираетесь сделать вашу программу сценария оболочки, вы не можете использовать eval
, source
или .
(как в функции, а не символ). Это сделало бы задачу слишком легкой, на мой взгляд.
Разумное нарушение правил допускается. Я явно запретил многие вещи, но я почти уверен, что вам все еще разрешено делать то, чего я не делал. Иногда я удивляюсь тому, как люди интерпретируют мои правила. Кроме того, помните, что вы можете сделать все, что я не упомянул. Например, если я пытаюсь использовать переменные, вы можете стереть жесткий диск (но, пожалуйста, не надо).
Самый короткий код выигрывает, так как это Codegolf.
источник
Ответы:
Bash (92 байта)
Воспользовавшись той же лазейкой, что и в этом ответе , вот гораздо более короткое решение:
Python (
247241239 байт)источник
*
), но в остальном это выглядит великолепно :-). Я удивлен, что новый участник сделал такое хорошее решение для сложной проблемы.C (340 байт)
У меня нет никакого опыта в игре в гольф, но вы должны начать где-нибудь, так что здесь идет:
Я добавил разрывы строк, чтобы вам не пришлось прокручивать их, но не включил их в мой счет, поскольку они не имеют смыслового значения. Те после директив препроцессора обязательны и были учтены.
Неуправляемая версия
Характеристики
'ec'ho He'll''o 'world
работают как должны. Вполне возможно, что код был бы проще без этой функции, поэтому я приветствую разъяснение, требуется ли это.Известные проблемы
execvp
сбоя вызова может произойти что угодно , например, из-за неверно набранного имени программы. Тогда у нас есть два процесса, играющих в оболочку одновременно.Специальные символы '|' и разрыв строки сохраняют свое особое значение внутри строк в кавычках. Это противоречит требованиям, поэтому я изучаю способы исправления этого.Исправлено, при стоимости около 11 байт.Другие заметки
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
зависал. Очевидно, проблема заключалась в закрытом канале записи, поэтому мне пришлось добавить эту команду закрытия, которая увеличила размер моего кода на 10 байт. Возможно, существуют системы, в которых такая ситуация не возникает, поэтому мой код может быть оценен на 10 байт меньше. Я не знаю.?:
может быть вложенным,
без(…)
.источник
int c, m, f[3];
наружуmain
, чтобы избежать объявления типов. Для глобальных переменных вам не нужно объявлятьint
. Но в общем, интересное решение.yes|head -3
продолжают работать вечно, а оболочка завершается после каждой отдельной команды. Я использую gcc версии 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu5) без каких-либо переключателей.#define B break;case
(break;
передdefault
становится)B-1:
), и 2, заменивcase'\n'
иcase'\''
) наcase 10
иcase 39
.Баш (+ экран) 160
Будет выводить что-то вроде:
источник
Фактор (208 символов)
Поскольку правила не запрещают передавать работу третьей стороне ( http://www.compileonline.com/execute_bash_online.php ), вот решение:
Вы можете написать программу как еще более короткую однострочную в repl ( 201 символ):
источник
Perl, 135 знаков
Эта оболочка делает некоторые глупые вещи. Запустите интерактивную оболочку
perl shell.pl
и попробуйте:ls
печатает в одном столбце, потому что стандартный вывод не является терминалом. Оболочка перенаправляет стандартный вывод в канал и читает из канала.perl -E 'say "hi"; sleep 1'
ждет 1 секунду, чтобы сказать привет, потому что оболочка задерживает вывод.dd
читает 0 байт, если это не первая команда этой оболочки. Оболочка перенаправляет стандартный ввод из пустого канала для каждого конвейера после первого.perl -e '$0 = screamer; print "A" x 1000000' | dd of=/dev/null
завершается успешно.perl -e '$0 = screamer; print "A" x 1000000' | cat | dd of=/dev/null
вешает раковину!pkill -f screamer
в другой оболочке), то оболочка возобновится.perl -e 'fork and exit; $0 = sleeper; sleep'
вешает раковину!'echo $((2+3))'
запускает команду в / bin / sh. Это поведение exec и системы Perl с одним аргументом, но только если аргумент содержит специальные символы.Неуправляемая версия
источник