Comando Bash: é possível passar um argumento antes de um comando personalizado (função) ou deve ser somente após:

2

Eu estou querendo saber se é possível passar um argumento para um comando personalizado antes do comando?

Digamos que eu tenha o comando personalizado ping e gostaria de passar o endereço IP antes do comando:

em vez disso ping 1.1.1.1 para ser 1.1.1.1 ping ?

Obrigado antecipadamente

    
por Lacho 18.02.2015 / 11:57

2 respostas

0

Isso funcionará para o exemplo de ping :

echo 1.1.1.1 | xargs ping

Argumento antes do comando

    
por 18.02.2015 / 12:01
0

Isso é um pouco complicado, mas parece funcionar principalmente:

cmd_handler() {
    eval "cmd_words=($BASH_COMMAND)"
    last_word="${cmd_words[@]: -1:1}"
    if [ "$last_word" = gnip ]
    then
        argcm1=$((${#cmd_words[@]}-1))
        ping "${cmd_words[@]:0:$argcm1}"
        return 1
    fi
}
shopt -s extdebug
trap cmd_handler debug

As primeiras dez linhas, obviamente, definem uma função chamada cmd_handler . O comando trap cmd_handler debug especifica que O bash deve chamar cmd_handler para cada comando digitado. O comando que você digitou, por exemplo, 1.1.1.1 ping , é disponibilizado para a função na variável $BASH_COMMAND . Esta é apenas uma string escalar, então usamos cmd_words=($BASH_COMMAND) para dividir em palavras. Isso causaria o comando hipotético

ls -l This is "Super User".

a ser dividido em seis palavras:

  • ls
  • -l
  • This
  • is
  • "Super e
  • User".

então usamos eval para fazer o shell interpretar as aspas. A construção ${array_name[@]:offset:length} rende os membros length do array começando com ${array_name[offset]} . Um offset de -1 refere-se ao último elemento; então, como o nome sugere, isso avalia a última palavra do comando. Inclua um espaço para que não pareça que você está dizendo :- . Se este é o nome do seu comando personalizado (que eu representei como gnip para fins de teste), calcular a contagem de argumentos menos 1 ( argcm1 ) e execute ping com todas as palavras, exceto os últimos como argumentos. return 1 para dizer ao shell para não tentar manipular este comando através da análise normal.

Encontrei algumas falhas e algumas soluções alternativas:

  • Obviamente, isso não manipulará 1.1.1.1 gnip -n 4 -w 500 .
    • Ele processará 1.1.1.1 -n 4 -w 500 gnip .
    • Você pode modificar cmd_handler para verificar cada palavra na linha de comando para o nome do seu comando personalizado.
  • 1.1.1.1 gnip > ping.out não funciona porque cmd_handler verá ping.out como a última palavra. Você pode usar

    • (1.1.1.1 gnip) > ping.out ou
    • { 1.1.1.1 gnip;} > ping.out

    O primeiro executará o comando em um subshell; o segundo não. Lembre-se que o segundo formulário requer um espaço após o { e um ponto e vírgula ( ; ) antes do } .

  • 1.1.1.1 gnip | some other command não vai funcionar e eu não entendo porque não. Você pode contornar isso dizendo (1.1.1.1 gnip) > >(some other command) , ou use o outro formulário, { 1.1.1.1 gnip;} > >(some other command) , se você quiser que seu comando seja executado no shell principal.

Existem provavelmente outras armadilhas que ainda não encontrei.

    
por 18.02.2015 / 20:30