Evitar a expansão de parâmetros no shell script

4

Muitas vezes tenho que fazer uma pesquisa recursiva em arquivos. Cansado de digitar toda a combinação "find / grep" o tempo todo, acabei de criar um script com a seguinte linha:

find . -name  -exec grep  {} + 2>/dev/null

A ideia é que eu seja capaz de executá-lo como, por exemplo:

myfind '*' hello

O problema é que quando '*' é passado para o script, o script é expandido para cada arquivo no diretório.

Eu tentei colocar uma cotação em torno de :

 find . -name '' -exec grep  {} + 2>/dev/null

No entanto, isso transforma em uma string literal.

Agradecemos sua ajuda para encontrar a sintaxe correta. Deve ser algo simples que eu esteja sentindo falta.

    
por Peter 09.07.2014 / 20:19

2 respostas

8

Eu já demonstrei o problema aqui:

$ pie() { echo ; }; pie '*'
1 2 3 4 5 file

Expandido. Incomodar-se.

Mas a solução é bem simples. Você só precisa citar, mas de uma forma que o bash vai entender. Nós usamos aspas duplas. Ele será substituído pelo conteúdo da variável, mas não será expandido.

$ pie() { echo ""; }; pie '*'
*
    
por Oli 09.07.2014 / 20:35
4

Você precisa se familiarizar com as regras básicas sobre a expansão de variáveis do shell.

NAME="start"

SE você apresentar $ NAME ao shell, ele será expandido para a string start

Se você colocar aspas simples em torno de uma string, o shell não expandirá o que estiver entre aspas simples, então '$ NAME' permanece como $ NAME

Agora, com aspas duplas, o shell expande a variável $ NAME para a string start , mas as aspas duplas impedem o que é conhecido como globalização de arquivos.

O que é arquivo globbing você pergunta?

Bem, você faz

ls -l *

você espera que o comando ls liste todos os arquivos. Não é ls que está convertendo * para todos os nomes de arquivos no diretório, mas o shell.

Agora, digamos que você tenha um arquivo chamado * em seu diretório e queira apenas listar esse arquivo, então você poderia usar

ls -l '*' 

ou

ls -l "*"

e as aspas simples e duplas impedem o shell de expandir o * para a lista de arquivos.

A globalização também pode ser desativada ao fazer

set noglob

Em vez de ter essa string de localização simples como um script de shell separado que requer que um novo shell seja invocado toda vez que for usado, a maneira mais eficiente é criar é como uma função de shell fs (find_string)

function fs ()
{
 \find . -type f -name "" -exec egrep --color "" {} /dev/null \;
}
    
por J G Miller 09.07.2014 / 20:49

Tags