bash personalizado incorporado

1

Eu estou querendo construir um builtin personalizado em bash - como time por exemplo. Isso é possível? Se não for, é possível em outro shell?

Por exemplo, eu quero fazer isso: map find -name '*.js' | xargs grep func1 e executá-lo find -name '*.js' | xargs grep func1 dentro de cada diretório dentro do CWD. Observe que tudo incluindo o pipe é passado para map .

O objetivo é aplicar um comando em vários diretórios. Eu escrevi um script chamado map , que eval s $1 em qualquer ls produz. No entanto, se o comando que eu quero executar incluir pipes, redirecionamentos, etc, então eu tenho que citar tudo dentro de uma string. Eu estou procurando uma maneira de não ter que fazer isso.

Além disso, estou simplesmente curioso para saber se isso é possível;)

    
por Alexander Bird 19.05.2017 / 15:09

2 respostas

2

ATT ksh, bash e zsh possuem um sistema de carregamento de módulos dinâmico que permite carregar código adicional em uma instância de shell existente, e o código carregado dinamicamente pode implementar novos builtins. O que você está pedindo requer mais do que um novo builtin: requer nova sintaxe, e eu acho que nenhuma das shells pode lidar com isso. Você teria que modificar o analisador no código-fonte do shell.

No zsh, você pode se aproximar da sintaxe desejada:

for x (*/) (cd $x && pipeline)

Você pode criar um alias alias map='for x (*/) (cd $x &&' , mas ainda precisará do parêntese de fechamento no final. Você pode obter exatamente a sintaxe desejada com um hack bruto:

alias map='map__PWD=$PWD; for x (./*/ "") cd $map__PWD${x#.}/ && [[ -z $x ]] || '

Isso é tão feio, frágil e não generalizável que não vou explicá-lo. Não pense em usá-lo se você não entender completamente como funciona.

    
por 20.05.2017 / 01:08
1

Nesse caso, algo como

find . -type f -name "*.js" -exec grep -qF "func1" {} \; -print

provavelmente seria o suficiente para encontrar os nomes dos arquivos *.js em qualquer lugar dentro ou abaixo do diretório atual que contém a string func1 .

Se você quiser evitar os arquivos que estão no diretório atual:

find . -mindepth 2 -type f -name "*.js" -exec grep -qF "func1" {} \; -print

Com -mindepth 2 , find não corresponderá a nada em "profundidade 1", ou seja, no diretório atual.

Essa última coisa basicamente faz o que você pede. Ele efetivamente executa grep em cada subdiretório do diretório atual.

    
por 19.05.2017 / 19:02