grep
(ou seja, /bin/grep
) será lido na entrada padrão
se for invocado sem argumentos de nome de arquivo.
Portanto, é simples escrever um script que execute grep
com entrada
da entrada padrão - basta invocar grep
sem argumentos de nome de arquivo.
Mas grep
deve receber (pelo menos) um argumento PADRÃO (ou equivalente).
Uma maneira extremamente inflexível de fazer isso,
que é improvável que seja muito útil na vida real,
é codificar uma string de pesquisa (padrão) em seu script grep; por exemplo,
#!/bin/sh
grep --color=always cat
que pode ser usado no contexto
ps | mygrep
e provavelmente não muito mais. Um script ligeiramente mais flexível pode usar uma variável de ambiente como a string de pesquisa:
#!/bin/sh
grep --color=always $USER
que pode ser usado no contexto
ps -ef | mygrep
e provavelmente não muito mais. A única solução razoável, realista e robusta é permitir que o usuário do script para fornecer uma string de pesquisa como um argumento de linha de comando:
#!/bin/sh
grep --color=always $1
que pode ser usado no contexto
dmesg | mygrep TCP
e pode realmente ser bastante útil.
Bem, talvez eu deva dizer algo útil. Isso se desfaz rapidamente como você pode precisar de vários argumentos para especificar os parâmetros de pesquisa:
mygrep -i tcp Case-insensitive search; find tcp, TCP, Tcp, etc. mygrep -v bash Find everything except bash. mygrep -e cat -e dog Find every line that contains cat or dog. mygrep -f wordlist Search strings are in a file.
O segundo esboço do nosso script pode ser:
#!/bin/sh
grep --color=always $1 $2 $3 $4 $5 $6 $7 $8 $9
que poderia lidar com qualquer um dos exemplos acima. Como um bônus extra, isso não precisa ser usado para ler a entrada padrão; podemos dizer
mygrep -i path .bashrc
e será executado
grep --color=always -i path .bashrc
Mas ainda não terminamos! Considere
mygrep "cat food" "shopping list.txt"
que será executado
grep --color=always cat food shopping list.txt
que irá (tentar) procurar por cat
em três arquivos:
food
, shopping
e list.txt
. OK, podemos lidar com isso dizendo
#!/bin/sh
grep --color=always "$1" "$2"
mas
#!/bin/sh
grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
não é uma boa resposta; vai virar
mygrep "cat food" "shopping list.txt"
em
grep --color=always "cat food" "shopping list.txt" "" "" "" "" "" "" ""
que fará o que você quiser, mas também emitirá sete mensagens de erro.
Então, o que fazer, o que fazer? Oh espere; Eu tenho uma marreta no meu armário:
#!/bin/sh
if [ "$1" = "" ]
then
printf "%s\n" "error: mygrep must be run with at least one argument."
elif [ "$2" = "" ]
then
grep --color=always "$1"
elif [ "$3" = "" ]
then
grep --color=always "$1" "$2"
elif [ "$4" = "" ]
then
grep --color=always "$1" "$2" "$3"
elif [ "$5" = "" ]
then
grep --color=always "$1" "$2" "$3" "$4"
elif [ "$6" = "" ]
then
grep --color=always "$1" "$2" "$3" "$4" "$5"
elif [ "$7" = "" ]
then
grep --color=always "$1" "$2" "$3" "$4" "$5" "$6"
elif [ "$8" = "" ]
then
grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7"
elif [ "$9" = "" ]
then
grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8"
else
grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
fi
Certo.
- Isso é ridiculamente impraticável.
-
Mesmo que falhe para
mygrep -e cat -e dog -e fish file1 file2 file3 file4
porque tem mais de nove argumentos! E, embora esta situação possa parecer improvável, o mesmo problema ocorre com
mygrep bird *
se houver mais de oito arquivos (não ocultos) no diretório atual.
Então, o que fazer, o que fazer?
TL; DR
Se você procurar em bash (1)
em Parâmetros especiais ,
você verá que $@
se expande para a lista de parâmetros posicionais,
começando de um. Quando a expansão ocorre entre aspas duplas,
cada parâmetro se expande para uma palavra separada.
Ou seja, "$@"
é equivalente a "$1"
"$2"
…
(conforme implementado no longo script, acima,
mas não limitado aos primeiros nove).
Então, a maneira de escrever um script para embrulhar
(isto é, atuar como um front-end para) algum comando, agindo como um alias, é
#!/bin/sh
grep --color=always "$@"