Jestem (naprawdę) nowicjuszem w programowaniu funkcjonalnym (w rzeczywistości miałem z nim kontakt tylko za pomocą Pythona), ale wydaje się być dobrym podejściem do niektórych zadań wymagających dużej ilości list w środowisku powłoki.
Chciałbym zrobić coś takiego:
$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]
Czy jest jakaś powłoka uniksowa z tego rodzaju funkcjami? A może jakaś funkcja umożliwiająca łatwy dostęp do powłoki (polecenia, env / vars, readline itp.) Z poziomu Pythona (pomysł polega na użyciu interaktywnego interpretera Pythona jako zamiennika bash).
EDYTOWAĆ:
Może wyjaśniłby to przykład porównawczy. Powiedzmy, że mam listę złożoną z katalogu / pliku :
$ FILES=( build/project.rpm build/project.src.rpm )
Chcę wykonać naprawdę proste zadanie: skopiuj wszystkie pliki do dist / AND zainstaluj je w systemie (jest to część procesu kompilacji):
Za pomocą bash:
$ cp $ {pliki [*]} dist / $ cd dist && rpm -Uvh $ (dla f w $ {pliki [*]}; do basename $ f; gotowe))
Korzystanie z podejścia „powłoki pythonowej” (uwaga: jest to urojony kod):
$ cp [os.path.join ('dist', os.path.basename (plik)) dla pliku w PLIKACH] 'dist'
Czy widzisz różnicę ? O tym właśnie mówię. Jak jeszcze nie wyjść z powłoki z tego typu wbudowanymi funkcjami? Naprawdę trudno jest obsługiwać listy w powłoce, nawet jeśli jest to tak częste zadanie: lista plików, lista PID, lista wszystkiego.
I naprawdę, bardzo ważny punkt: używając składni / narzędzi / funkcji, które wszyscy już znają: sh i python.
IPython wydaje się być w dobrym kierunku, ale jest rozdęty: jeśli nazwa var zaczyna się od „$”, robi to, jeśli „$$” to robi. Jego składnia nie jest „naturalna”, więc wiele reguł i „obejść” ( [ ln.upper() for ln in !ls ]
-> błąd składni)
Odpowiedzi:
Istnieje Skorupa Schematu, która prawdopodobnie jest bardzo zbliżona do tego, czego szukasz. Sam go nie użyłem.
AKTUALIZACJA :
Właśnie zainstalowałem i sam wypróbowałem. Wygląda na to, że scsh jest bardziej interaktywnym interpretatorem Scheme i językiem skryptowym niż naprawdę użyteczną interaktywną powłoką. Nie możesz po prostu pisać
wydaje się, że składnia jest
i znalezienie go zajęło Google kilka minut. Pierwszy przykład tutaj :
co przekłada się na:
ale to nie mówi, jak uruchomić proste polecenie powłoki.
Ten wpis FAQ mówi:
Więc może to jest prawdziwa odpowiedź.
źródło
W kategorii bezpośredniej odpowiedzi na pytanie znajduje się powłoka ES, która jest przeznaczona jako funkcjonalny zamiennik dla Bash i Zsh itp.
Po drugie, w kategorii pomocy w pisaniu bardziej funkcjonalnej standardowej powłoki, zastanów się nad techniką pipemill:
Pierwsza pętla while jest funkcjonalna
keep
(przekazuje tylko niepuste wartości, które wychodzą z pętli), a druga toeach
(mapa tylko efektów ubocznych).Jest to ogromny impuls do fp w pociskach.
Możliwe jest wyrażanie wielu rzeczy w stylu fp w powłoce, to po prostu nie jest tak łatwe, jak mogłoby być. Wydaje się, że nie ma większego zainteresowania tworzeniem lepszych pocisków, mimo że wszyscy tak często ich używamy.
źródło
Standardowe muszle stylu Bourne'a (
sh
,bash
,ksh
, itd.) Już pozwolić zrobić:(Zwróć uwagę na potrzebę używania średników przed
do
idone
.) Dodatkowo wbash
i innych powłokach, jeśli$repo
pojawia się tylko raz w poleceniu, możesz napisać:źródło
git clone $host/{repo1,repo2,repo3}
nie robi tego samego, cofor
pętla; przywołujegit clone
raz z trzema argumentami. Fakt, że robi to w zasadzie to samo, jest artefaktem tego, jakgit clone
działa; niekoniecznie dotyczy innych poleceń. (Porównajecho foo bar baz
celuecho foo; echo bar; echo baz
, na przykład.)FUN=eval 'git clone '"$host"'$0
do zdefiniowania lambda do użycia jakofor repo in repo{1,2,3} ; do $FUN $repo ; done
Schemat Shell, scsh, jest naprawdę dobry.
Jak zauważa Keith Thompson, nie jest on przydatny jako interaktywna powłoka (chociaż Commander S wygląda jak interesujący eksperyment). Zamiast tego jest to doskonały język programowania dla kontekstów, w których przydatne są wszystkie wiązania POSIX - w tym przypadki, w których chcesz wywoływać inne aplikacje uniksowe. Skrypt powłoki składający się z kilkudziesięciu wierszy zawsze będzie przypominał włamanie, bez względu na to, jak dobrze piszesz
sh
; w przeciwieństwie do tego nic nie powstrzymuje Cię przed pisaniem znaczących programów przy użyciu scsh.scsh nie jest zbyt kompaktowy (zwięzłość jest zarówno siłą, jak i słabością języków rodziny sh), ale jest potężny.
Ponieważ jest przydatny i praktyczny w przypadku małych i dużych zadań, scsh jest zresztą dobrym sposobem na opanowanie programu (chociaż, jeśli to był twój cel, równie dobrze możesz teraz przejść bezpośrednio do Rakiety).
Zalety języków funkcjonalnych nie dotyczą tylko zadań wymagających dużej ilości list (choć z powodu ich historii preferują listy jako strukturę danych) - to naprawdę niezawodny sposób na pisanie programów, gdy wypijesz odpowiedni kool- pomoc.
Nie ma sensownego sensu, w którym powłoki w stylu sh są funkcjonalne, a Python działa tylko w marginalnym sensie, że ma funkcję lambda.
źródło
Muszle są niezwykle wyraziste, co oznacza, że osiągasz dużo przy mniejszej liczbie linii, tokenów itp.
Zazwyczaj wyrażamy języki, projektując je do specjalnego celu, takiego jak powłoki lub DSL, takie jak R, klon itp. W większości języków ogólnego przeznaczenia, takich jak C, C ++, Java itp., Można znaleźć stosunkowo mało wyrazistości.
Python, Perl, Ruby itp. To języki ogólnego przeznaczenia, które są bardziej ekspresyjne w sposób podobny do powłok, ala pisanie kaczek. Więc DSL przyspawane do nich, mędrca do matematyki. Jednak nie jest tak świetny do rzeczywistych poleceń powłoki .
Schemat nie jest tak wyrazisty, nawet po zbudowaniu DLS, ze względu na wszystkie nawiasy.
Istnieją jednak języki funkcjonalne, takie jak Haskell, z ogromną ekspresją i dużą zdolnością do tworzenia DSL. Ciekawym wysiłkiem zbudowania muszli na Haskell są żółwie i schronienia .
W praktyce istnieje krzywa uczenia się z narzędziami wysiłkowymi ze względu na potężny, ale restrykcyjny system Haskell, ale są one bardzo obiecujące.
źródło
Po pierwsze, powinieneś używać
"${files[@]}"
wszędzie, gdzie masz${files[*]}
. W przeciwnym razie spacje zepsują cię.Powłoka jest już dość funkcjonalna; jeśli myślisz, że w kategoriach tekstu wyjściowego są to listy linii, to
grep
znaczyfilter
,xargs
jestmap
itd. Rury są bardzo funkcjonalne.Powłoka nie jest wprawdzie najbardziej przyjaznym środowiskiem programistycznym, ale znacznie lepiej nadaje się do użytku interaktywnego niż Python. I ma tę bardzo przyjemną cechę, że interfejs API i interfejs użytkownika są identyczne - ucz się obu naraz.
Nie rozumiem, dlaczego uważasz, że
cp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist'
lepiejcp "${FILES[@]}" dist
. Ten ostatni jest o wiele mniej pisania.źródło
Nie wiem o tym, że jest „funkcjonalny”, ale jest też rc , o którym wspomina papier scsh . Jest to poprzednik es.
W Linux Mint (i prawdopodobnie Debian, Ubuntu ...) możesz tego spróbować
źródło