Я (действительно) новичок в функциональном программировании (на самом деле имел дело только с ним с помощью Python), но, похоже, является хорошим подходом для некоторых задач с интенсивным списком в среде оболочки.
Я хотел бы сделать что-то вроде этого:
$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]
Есть ли оболочка Unix с такими функциями? Или, может быть, какая-то функция, позволяющая легкий доступ к оболочке (команды, env / vars, readline и т. Д.) Изнутри python (идея состоит в том, чтобы использовать интерактивный интерпретатор python вместо замены bash).
РЕДАКТИРОВАТЬ:
Может быть, сравнительный пример уточнит. Допустим, у меня есть список, состоящий из dir / file :
$ FILES=( build/project.rpm build/project.src.rpm )
И я хочу сделать действительно простую задачу: скопировать все файлы в dist / и установить его в системе (это часть процесса сборки):
Используя bash:
$ cp $ {files [*]} dist / $ cd dist && rpm -Uvh $ (для f в $ {files [*]}; сделать базовое имя $ f; сделано))
Используя подход «pythonic shell» (осторожно: это воображаемый код):
$ cp [os.path.join ('dist', os.path.basename (file)) для файла в файлах] 'dist'
Вы видите разницу? Вот о чем я говорю. Как еще нельзя выйти из оболочки с такими встроенными вещами? Работать со списками в оболочке очень сложно, даже если это такая распространенная задача: список файлов, список идентификаторов PID, список всего.
И действительно, очень важный момент: используя синтаксис / инструменты / функции, которые все уже знают: sh и python.
IPython выглядит хорошо, но он раздут: если имя переменной начинается с «$», он делает это, если «$$» это делает. Это синтаксис не "естественный", так много правил и "обходных путей" ( [ ln.upper() for ln in !ls ]
-> синтаксическая ошибка)
Ответы:
Существует оболочка Scheme, которая, вероятно, очень близка к тому, что вы ищете. Я не использовал это сам.
ОБНОВИТЬ :
Я только что установил и попробовал это сам. Похоже, что scsh - больше интерактивный интерпретатор Scheme и язык сценариев, чем действительно полезная интерактивная оболочка. Вы не можете просто напечатать
синтаксис выглядит так
и потребовалось несколько минут, чтобы найти это. Первый пример здесь :
что переводится как:
но это не говорит вам, как запустить простую команду оболочки.
Эта запись часто задаваемых вопросов говорит:
Так что, возможно, это реальный ответ.
источник
В категории прямого ответа на вопрос есть оболочка ES, которая предназначена для функциональной замены Bash, Zsh и т. Д.
Во-вторых, в категории, помогающей вам написать более функциональную стандартную оболочку, рассмотрите изучение техники pipemill:
Первый цикл while - это функционал
keep
(передает только ненулевые значения, которые выходят из цикла), а второй -each
(отображение только для побочных эффектов).Это огромный импульс для fp в снарядах.
Можно выразить многие вещи в стиле fp в оболочке, это не так просто, как могло бы быть. Похоже, что делать лучшие снаряды не очень интересно, хотя мы все так часто их используем.
источник
Стандартные оболочки Bourne-стиль (
sh
,bash
,ksh
и т.д.) уже позволяют сделать:(Обратите внимание на необходимость использования точек с запятой перед
do
иdone
.) Кроме того, вbash
и других оболочках, если$repo
в команде появляется только один раз, вы можете написать:источник
git clone $host/{repo1,repo2,repo3}
не делает то же самое, что иfor
цикл; он вызываетgit clone
один раз с тремя аргументами. Тот факт, что, по сути, делает то же самое, является артефактом того, какgit clone
работает; это не обязательно относится к другим командам. (Сравнитеecho foo bar baz
сecho foo; echo bar; echo baz
, например.)FUN=eval 'git clone '"$host"'$0
для определения лямбда-for repo in repo{1,2,3} ; do $FUN $repo ; done
Схема Shell, scsh, действительно хороша.
Как отмечает Кит Томпсон, он не используется в качестве интерактивной оболочки (хотя Commander S выглядит как интересный эксперимент). Это отличный язык программирования для контекстов, где полезно использовать все привязки POSIX, включая случаи, когда вы хотите вызывать другие приложения Unix. Сценарий оболочки из нескольких десятков строк всегда будет выглядеть как хак, независимо от того, насколько аккуратно вы пишете
sh
; напротив, ничто не мешает вам писать важные программы с использованием scsh.scsh не очень компактен (краткость - это сила и слабость языков семейства sh), но он мощный.
Поскольку он полезен и практичен для малых и больших задач, scsh - хороший способ справиться со Схемой (хотя, если это и стало вашей целью, в эти дни вы могли бы также пойти прямо в Racket).
Преимущества функциональных языков не только для задач, требующих большого количества списков (хотя из-за их истории они предпочитают списки в качестве структуры данных) - это действительно надежный способ написания программ после того, как вы выпили нужное количество. помощь.
Нет никакого осмысленного смысла в том, что оболочки в стиле sh являются функциональными, а Python функционален только в предельном смысле, что у него есть лямбда-функция.
источник
Оболочки обязательно чрезвычайно выразительны, а это значит, что вы добиваетесь большего с меньшим количеством линий, токенов и т. Д.
Мы обычно делаем языки выразительными, проектируя их для специальных целей, таких как оболочки или DSL, такие как R, maple и т. Д. И вы обнаружите относительно небольшую выразительность в большинстве языков общего назначения, таких как C, C ++, Java и т. Д.
Python, Perl, Ruby и т. Д. Являются языками общего назначения, которые более выразительны в способах, аналогичных оболочкам, а также типизированным утиным типом. Так что DSL привариваются к ним, аля Sage для математики. Не очень хорошо для реальных команд оболочки, хотя .
Схема не так уж и выразительна, даже когда вы строите DLS, из-за всех круглых скобок.
Однако существуют такие функциональные языки, как Haskell, с огромной выразительностью и большими возможностями для создания DSL. Интересными усилиями по созданию панциря на Хаскелле являются черепаха и ракушка .
На практике, благодаря мощной, но ограничивающей системе типов Haskell, есть кривая обучения с инструментами усилий, но они показывают значительные перспективы.
источник
Во-первых, вы должны использовать
"${files[@]}"
везде, где у вас есть${files[*]}
. В противном случае пробелы запутают вас.Оболочка уже довольно функциональна; если вы думаете, что с точки зрения вывода текста это списки строк, то
grep
естьfilter
,xargs
естьmap
и т. д. Каналы очень функциональны.Оболочка, по общему признанию, не самая дружественная среда программирования, но она гораздо больше подходит для интерактивного использования, чем Python. И у этого есть очень хорошая особенность, что API и интерфейс идентичны - изучите оба сразу.
Я не понимаю, почему вы считаете это
cp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist'
предпочтительнымcp "${FILES[@]}" dist
. Последний гораздо меньше печатает.источник
Не знаю, что это «функционально», но есть и rc , о котором упоминается в scsh paper . Это предшественник эс.
На Linux Mint (и, возможно, Debian, Ubuntu ...) вы можете попробовать это с
источник