Existe algum shell unix funcional?

18

Sou (realmente) novato em programação funcional (na verdade, só tive contato com ele usando python), mas parece ser uma boa abordagem para algumas tarefas que exigem muita lista em um ambiente de shell.

Adoraria fazer algo assim:

$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]

Existe algum shell Unix com esse tipo de recurso? Ou talvez algum recurso que permita fácil acesso ao shell (comandos, env / vars, readline, etc ...) de dentro do python (a idéia é usar o interpretador interativo do python como substituto do bash).

EDITAR:

Talvez um exemplo comparativo seja esclarecido. Digamos que eu tenha uma lista composta de dir / file :

$ FILES=( build/project.rpm build/project.src.rpm )

E eu quero fazer uma tarefa muito simples: copiar todos os arquivos para dist / E instalá-lo no sistema (é parte de um processo de compilação):

Usando o bash:

$ cp ${files[*]} dist/
$ cd dist && rpm -Uvh $(for f in ${files[*]}; do basename $f; done))

Usando uma abordagem "shell pythonic" (cuidado: este é o código imaginário):

$ cp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist'

Você consegue ver a diferença? É disso que estou falando. Como não pode sair de um shell com este tipo de material ainda? É realmente difícil lidar com listas no shell, mesmo sendo uma tarefa tão comum: lista de arquivos, lista de PIDs, lista de tudo.

E, realmente, um ponto importante: usando a sintaxe / tools / features que todos já conhecem: sh e python.

O IPython parece estar em uma boa direção, mas está inchado: se o nome var começar com '$', ele fará isso, se '$$' fizer isso. Sua sintaxe não é "natural", muitas regras e "soluções alternativas" (erro de sintaxe [ ln.upper() for ln in !ls ] - >)

    
por caruccio 18.04.2012 / 20:42

7 respostas

9

Existe um Scheme Shell que provavelmente está muito próximo do que você está procurando. Eu não usei isso sozinho.

ATUALIZAÇÃO:

Eu acabei de instalar e tentei eu mesmo. Parece que o scsh é mais um interpretador Scheme interativo e uma linguagem de script do que um shell interativo realmente útil. Você não pode simplesmente digitar

echo hello

a sintaxe parece ser

(run (echo hello))

e demorou vários minutos pesquisando apenas para descobrir isso. O primeiro exemplo aqui é:

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

que se traduz em:

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

mas isso não diz a você como executar um comando shell simples .

Esta entrada de FAQ diz:

4.6 Can I use scsh as an interactive shell?

Well, technically you can: just run the "scsh" command and you will enter a Scheme 48 session with all scsh functions available. However, this is definitely not suitable for interactive work: there is no command-line editing, no command-line history, no file/function name completion, no terse syntax, etc.

To alleviate these problems, Martin Gasbichler and Eric Knauel have written Commander S, which runs on top of scsh and provides a comfortable interactive environment. One of its novel features is that it can understand the output of many Unix commands, and allows the user to browse and manipulate it in useful ways. More information about Commander S can be found in the paper describing it: http://www.deinprogramm.de/scheme-2005/05-knauel/05-knauel.pdf Instructions about how to obtain and install Commander S are available from the scsh Web site: http://www.scsh.net/resources/commander-s.html

Então talvez essa seja a verdadeira resposta.

    
por 18.04.2012 / 20:59
6

As conchas padrão Bourne ( sh , bash , ksh , etc.) já permitem:

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

(Observe a necessidade de ponto e vírgula antes de do e done .) Além disso, em bash e outras camadas, se $repo aparecer apenas uma vez no comando, você pode escrever:

git clone $host/{repo1,repo2,repo3}
    
por 18.04.2012 / 20:47
5

Na categoria de responder diretamente à pergunta, há o ES shell que serve como um substituto funcional para Bash e Zsh, etc.

Em segundo lugar, na categoria de ajudar você a escrever um shell padrão mais funcional, considere aprender a técnica de pipilagem:

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

O primeiro loop while é um keep funcional (passe apenas os valores não nulos que saem do loop) e o segundo é um each (mapear apenas para efeitos colaterais).

Este é um tremendo impulso para o fp em shells.

É possível expressar muitas coisas em um estilo mais fp em um shell, simplesmente não é tão fácil quanto poderia ser. Parece que não há muito interesse em fazer shells melhores, mesmo que todos nós os utilizemos muito.

    
por 19.08.2014 / 00:18
2

Primeiro, você deve usar "${files[@]}" em todos os lugares em que tem ${files[*]} . Caso contrário, os espaços vão bagunçar você.

O shell já é bastante funcional; se você pensar em termos de saída de texto como listas de linhas, então grep é filter , xargs é map , etc. Os canos são muito funcionais.

O shell não é reconhecidamente o ambiente de programação mais amigável, mas é muito mais adequado ao uso interativo do que o Python. E tem o ótimo recurso que a API e a interface do usuário são idênticas - aprenda as duas de uma só vez.

Não entendo por que você acha cp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist' preferível a cp "${FILES[@]}" dist . Este último é muito menos digitação.

    
por 17.10.2013 / 02:37
1

Scheme Shell, scsh, é muito bom.

Como Keith Thompson observa, não é útil como um shell interativo (embora o Commander S pareça um experimento interessante). Em vez disso, é uma excelente linguagem de programação para contextos em que ter todas as ligações POSIX é útil - isso inclui casos em que você deseja chamar outros aplicativos unix. Um shell script de mais de algumas dúzias de linhas sempre parecerá um hack, não importa o quão bem você escreva sh ; em contraste, não há nada que o impeça de escrever programas significativos usando scsh.

O scsh não é muito compacto (a brevidade é tanto a força quanto a fraqueza das linguagens sh-family), mas é poderoso.

Por ser útil e prático para pequenas e grandes tarefas, o scsh é, aliás, uma boa maneira de se familiarizar com um Scheme (embora, se esse fosse o seu objetivo, você também poderia ir direto para a Racket) .

As vantagens das linguagens funcionais não são apenas para tarefas intensivas de lista (embora, por causa de sua história, elas tendem a favorecer listas como estrutura de dados) - é uma maneira realmente robusta de obter programas escritos, kool-aid direito.

Não existe um sentido significativo em que as shells sh-style sejam funcionais, e Python só é funcional no sentido marginal de ter uma função lambda.

    
por 18.04.2012 / 23:30
0

Não sei se é "funcional", mas também há rc , que o scsh paper menciona. É um predecessor para es.

No Linux Mint (e provavelmente Debian, Ubuntu ...) você pode tentar com

sudo apt-get install rc
man rc
rc
    
por 16.02.2015 / 16:30
0

Os shells são necessariamente extremamente expressivos, o que significa que você consegue lotes com menos linhas, tokens etc.

Geralmente, tornamos as linguagens expressivas projetando-as para um propósito especial, como shells ou DSLs como R, maple etc. E você encontra relativamente pouca expressividade na maioria das linguagens de propósito geral como C, C ++, Java, etc.

Python, Perl, Ruby, etc. são linguagens de propósito geral que são mais expressivas de formas parecidas com shells, tipagem de pato de ala. Então, as DSLs são soldadas nelas, Sage para matemática. Não é tão bom para comandos de shell reais .

O esquema não é tão expressivo, mesmo depois de construir um DLS, devido a todos os parênteses.

No entanto, existem linguagens funcionais como Haskell com enorme expressividade e grande capacidade de construir DSLs. Um esforço interessante para construir uma concha em Haskell é tartaruga e shelly .

Na prática, há uma curva de aprendizado com ferramentas de esforços devido ao sistema de tipos poderoso mas restritivo de Haskell, mas elas são promissoras.

    
por 21.02.2015 / 02:46

Tags