Чи є якась функціональна оболонка Unix?


18

Я (справді) новачок у функціональному програмуванні (насправді мав контакт із ним лише за допомогою 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 / AND встановити його в систему (це частина процесу збирання):

Використання bash:

$ cp $ {файли [*]} dist /
$ cd dist && rpm -Uvh $ (для f у $ {файлах [*]}; виконайте базове ім’я $ f; виконано))

Використання підходу "пітонічна оболонка" (обережність: це уявний код):

$ cp [os.path.join ('dist', os.path.basename (файл)) для файлу у FILES] 'dist'

Ви можете бачити різницю? ТО про що я говорю. Як ще не можна вийти з оболонки з такими вбудованими матеріалами? Справжній біль обробляти списки в оболонці, навіть це настільки поширене завдання: список файлів, список PID, список всього.

І дійсно, дійсно, важливий момент: використання синтаксису / інструментів / функцій, які всі вже знають: sh та python.

IPython шви повинні бути в хорошому напрямку, але він роздутий: якщо ім'я var починається з "$", це робить це, якщо "$$" - це робить. Його синтаксис не є "природним", тому багато правил і "обхідних шляхів" ( [ ln.upper() for ln in !ls ] -> помилка синтаксису)


Дещо пов’язане: github.com/amoffat/pbs
Джош Лі


4
Існує трохи більше, ніж розуміння списку функціонального програмування. Якщо ваш головний фокус - це написання функціонального коду, я б не брав python як приклад.
pqnet

Відповіді:


10

Там в схемі Shell , яка, ймовірно , дуже близько до того , що ви шукаєте. Я сам не користувався цим.

ОНОВЛЕННЯ:

Я щойно встановив і спробував сам. Здається, що scsh - це скоріше інтерактивна інтерпретаторна схема та мова сценаріїв, ніж дійсно корисна інтерактивна оболонка. Ви не можете просто ввести

echo hello

синтаксис, здається, є

(run (echo hello))

і знадобилося кілька хвилин Гуглінгу, щоб знайти це. Перший приклад тут :

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

що перекладається на:

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

але це не говорить про те, як запустити просту команду оболонки.

У цьому записі поширених запитань сказано:

4.6 Чи можна використовувати scsh як інтерактивну оболонку?

Ну, технічно ви можете: просто запустіть команду "scsh", і ви введете сеанс схеми 48 із усіма доступними функціями scsh. Однак це, безумовно, не підходить для інтерактивної роботи: немає редагування командного рядка, немає історії командного рядка, немає завершення імені файлу / функції, немає короткого синтаксису тощо.

Щоб полегшити ці проблеми, Мартін Гасбіхлер та Ерік Кнауель написали Commander S, який працює на вершині scsh та забезпечує комфортне інтерактивне середовище. Однією з його нових можливостей є те, що він може зрозуміти вихід багатьох команд Unix і дозволяє користувачеві переглядати та керувати ним корисними способами. Більш детальну інформацію про Commander S можна знайти в документі, що описує його: http://www.deinprogramm.de/scheme-2005/05-knauel/05-knauel.pdf Інструкції про те, як отримати та встановити Commander S, можна отримати в scsh Веб-сайт: http://www.scsh.net/resources/commander-s.html

Тож, можливо, це справжня відповідь.


7

У категорії прямо відповіді на питання є оболонка ES, яка призначена як функціональна заміна Bash і Zsh тощо.

По-друге, в категорії, яка допоможе вам написати більш функціональну стандартну оболонку, розгляньте вивчення техніки трубопроводу:

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

Перший цикл while є функціональним keep(передайте лише ненульові значення, які виходять з циклу), а другий - an each(карта лише для побічних ефектів).

Це приголомшливий приріст, який поширюється в снарядах.

Можна виразити багато речей у більш fp стилі в оболонці, це просто не так просто, як це може бути. Здається, що не так багато інтересу до виготовлення кращих снарядів, хоча ми всі їх так багато використовуємо.


6

Стандартні оболонки Bourne-стиль ( sh, bash, kshі т.д.) вже дозволяють зробити:

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

(Зверніть увагу на необхідність крапки з комою до doта done.) Крім того, у bashта інших оболонках, якщо $repoв команді відображається лише один раз, ви можете записати:

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

звичайно, і я цим дуже користуюся. а як щодо інших речей, наприклад лямбда-функцій?

8
git clone $host/{repo1,repo2,repo3}не робить те саме, що і forцикл; він викликає git cloneодин раз трьома аргументами. Те, що робить по суті те саме, є артефактом того, як git cloneпрацює; це не обов'язково стосується інших команд. (Порівняйте echo foo bar bazз echo foo; echo bar; echo baz, наприклад.)
Кітом Томпсон

@caruccio ви можете використовувати FUN=eval 'git clone '"$host"'$0 для визначення лямбда для використання якfor repo in repo{1,2,3} ; do $FUN $repo ; done
pqnet

Найбільша проблема полягає в тому, що інструменти unix часто мають побічні ефекти (наприклад, запис у файли), тому ви часто не можете складати їх так, як хотіли б робити на функціональній мові.
weberc2

2

Схема Shell, scsh, справді гарна.

Як зазначає Кіт Томпсон, він не корисний як інтерактивна оболонка (хоча Commander S виглядає як цікавий експеримент). Натомість це чудова мова програмування для контекстів, де корисні всі прив’язки POSIX - що включає випадки, коли ви хочете викликати інші програми Unix. Сценарій оболонки, що складається з декількох десятків рядків, завжди буде відчувати себе злому, незалежно від того, наскільки акуратно ви пишете sh; навпаки, ніщо не заважає писати значні програми за допомогою scsh.

scsh не дуже компактний (стислість - це і сила, і слабкість мов сімейства sh), але він потужний.

Оскільки це корисно і практично для малих і великих завдань, scsh - це, до речі, хороший спосіб налагодити схему (хоча, якщо це сталося для вас метою, ви можете також перейти прямо до Ракетки в ці дні).

Переваги функціональних мов полягають не лише у завданнях, що потребують списку (хоча через їхню історію вони надають перевагу спискам як структурі даних) - це дійсно надійний спосіб написання програм, як тільки ви п'єте потрібну команду, допомогу.

Немає змістовного сенсу, в якому оболонки у стилі sh функціональні, а Python функціональний лише в граничному сенсі, що він має лямбда-функцію.


2

Оболонки обов'язково надзвичайно виразні, це означає, що ви досягаєте жереб з меншою кількістю ліній, жетонів тощо.

Ми зазвичай робимо мови виразними, створюючи їх для особливих цілей, як оболонки або DSL, такі як R, клен тощо.

Python, Perl, Ruby тощо - це мови загального призначення, які є більш виразними способами, схожими на оболонки, набираючи ala duck. Тож DSL зварюються на них, аля шавлія з математики. Хоча це не так добре для фактичних команд оболонки .

Схема не є такою виразною, навіть коли ви створюєте DLS, завдяки всім дужкам.

Однак є функціональні мови, такі як Haskell, з величезною виразністю та великою спроможністю для створення DSL. Цікавими зусиллями для побудови снарядів на Haskell є черепахи та шеллі .

На практиці існує крива навчання з інструментами зусиль завдяки потужній, але обмежувальній системі Haskell, але вони демонструють значну перспективу.


1

По-перше, ви повинні використовувати "${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. Останнє набагато менше набирається.


0

Не знайте, як це "функціонально", але є також rc , про який згадує scsh paper . Це попередник es.

На Linux Mint (і, можливо, Debian, Ubuntu ...) ви можете спробувати це

sudo apt-get install rc
man rc
rc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.