Parâmetros: várias opções um argumento [RESOLVIDO]

1. Parâmetros: várias opções um argumento [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 02/12/2012 - 15:53h

Qual a melhor maneira de se criar algo como os parâmetros do tar ou ps (ps aux, tar zxf) em shell script?


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 02/12/2012 - 23:02h

Particularmente, acho que opções sem o traço devem ser evitadas ao máximo, justamente para ficar claro que são opções.

Gosto à parte, tenho as seguintes sugestões sobre seu código.

1) Troque aquele size=`echo ${#1}` simplesmente pot size=${#1}.

2) Se você estiver usando bash ou ksh para interpretar o script, use [[ ... ]] em lugar de [ ... ] para fazer seus testes condicionais, pois a primeira forma é um comando interno do shell, enquanto a segunda é um comando externo (que, para ser executado, implica criar um processo novo, chamar o programa externo e esperar esse comando acabar para verificar se o valor de saída dele é verdadeiro ou falso).

3) A comparação entre de $size e 0 pode ser numérica, em lugar de string, podendo, portanto, usar o operador -ne, em lugar de !=,


Note, porém, que, no fim das contas, seu código provavelmente não está funcionando.

Para ver, faça o "chinês": se suas opções forem dadas pela string "natup", na primeira iteração size valerá 5 e current valerá 4. Com isso, o argumento do case será ${1:4:5} (cujo sentido é: uma substring de $1, começando após o quarto caráter e se estendendo pelos próximos 5 caracteres), que vale 'p'. Na segunda iteração, size valerá 4 e current, 3, de modo que ${1:3:4} será 'up'. Depois, ${1:2:3} será 'tup', ${1:1:2} será 'at', e ${1:0:1} será 'n'.

O último argumento da construção de substring (i.e.: o tamanho na avalição de ${variavel:posicao:tamanho}) certamente deve ser sempre igual a 1 (e, como é fixo, não precisa ficar guardado em nenhuma variável, mas aplicado diretamente), já que você quer testar caráter a caráter. E você deve variar o valor de current de 0 até $((size-1)).

3. Re: Parâmetros: várias opções um argumento [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 02/12/2012 - 18:52h

leolfm escreveu:

Qual a melhor maneira de se criar algo como os parâmetros do tar ou ps (ps aux, tar zxf) em shell script?


Elegante? Fácil? Eficiente?


size=`echo ${#1}`

while [ $size != 0 ]
do
let "current=size-1"

case ${1:$current:$size} in
'f') foo
;;
'b') bar
;;
esac

let "size=size-1"
done




4. Re: Parâmetros: várias opções um argumento [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 03/12/2012 - 22:13h

Obrigado pela resposta :-)

Particularmente falando, suas respostas são sempre bastantes didáticas em qualquer tópico.


#!/bin/bash

size=$((${#1}-1))
current=0

while [[ $current -le $size ]]
do
case ${1:$current:1} in
'f') echo "foo"
;;
'b') echo "bar"
;;
'c') echo "cat"
;;
'd') echo "dog"
;;
esac
current=$((current+1))
done


Será que daria pra deixar melhor e simples? (while pelo for por exemplo)
Meu código só tinha duas opções, e pras duas aquela lógica funcionava. Mas no fundo eu não tinha entendido o conceito de substring (ou lembrado).
Interessante saber sobre os colchetes e escrever $((variavel,operação)) é muito mais elegante o que o let, tava achando ele feiozinho ali mesmo :-P


5. Re: Parâmetros: várias opções um argumento [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 04/12/2012 - 09:08h

Você pode trocar aquele -le por -lt. Como está, você faz uma iteração a mais do que o necessário, passando ao case uma string vazia (no caso do seu programa, não deu problema; mas se você tivesse um caso de uso default, como "*)", ele seria executado).

Você pode economizar alguns caracteres trocando size=$((${#1}-1)) por ((size=${#1}-1)) e current=$((current+1)) por ((current++)).


6. Re: Parâmetros: várias opções um argumento [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 04/12/2012 - 15:38h

paulo1205 escreveu:

Você pode trocar aquele -le por -lt. Como está, você faz uma iteração a mais do que o necessário, passando ao case uma string vazia (no caso do seu programa, não deu problema; mas se você tivesse um caso de uso default, como "*)", ele seria executado).

Você pode economizar alguns caracteres trocando size=$((${#1}-1)) por ((size=${#1}-1)) e current=$((current+1)) por ((current++)).


Obrigado.

Uma última coisa agora, entendi o conceito de [...] e [[...]], o que seria ((..))?


7. Re: Parâmetros: várias opções um argumento [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 04/12/2012 - 17:59h

Na verdade, eu não sei direito (sério! -- eu não costumo programar em shell). O que a documetção diz é que ((expr)) é a mesma coisa que let "expr". A grande diferença entre os dois é que let aceita múltiplas expressões de uma só vez (por exemplo: let "a+=5" "b=a*c").






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts