Argumentos de shell persistentes

3

Muitas vezes me vejo executando uma série de comandos em um único conjunto de argumentos.

Por exemplo:

$ nmap -Pn -sS 192.168.1.5
$ ssh 192.168.1.5
$ curl 192.168.1.5
$ wget -r 192.168.1.5

Isso pode ser acelerado colocando o (s) argumento (s) em uma variável,

$ a=192.168.1.5
$ nmap -Pn -sS $a
$ ssh $a
$ curl $a
$ wget -r $a

e acelerou ainda mais usando algumas funções, como as seguintes.

$ more .zshrc
...
paa() { PERSIST_ARGS+=("$@"); }
pa() { eval "$@" "${PERSIST_ARGS[@]}"; }
...
$ paa 192.168.1.5
$ pa nmap -Pn -sS
$ pa ssh
$ pa curl
$ pa wget -r

Existe uma maneira de acelerar ainda mais isso? Por exemplo,

$ <start special mode> 192.168.1.5
$ nmap -Pn -sS
$ ssh
$ curl
$ wget -r
$ <exit special mode>

Estou procurando por bash ou zsh solutions. A solução tem que trabalhar com um conjunto arbitrário de comandos.

    
por Gilles 26.05.2013 / 15:53

3 respostas

4

Alt -_ já insere a última palavra do último comando. Para mim, isso é bom o suficiente, mas você pode adicionar outra ligação de chave que insira um espaço, a última palavra e aceite a linha ( Enter ).

Com tcsh ou zsh (para Alt-S , S para same ):

bindkey -s '\es' ' \e_\r'

com bash :

bind '"\es": " \e_\r"'

Em seguida, digite:

$ nmap -Pn -sS 192.168.1.5
$ ssh<Alt-S>
$ curl<Alt-S>
...

Em zsh e tcsh , pelo menos, o argumento numérico (que é quando você prefixar com Alt- < number > ) será aplicado a o caractere de espaço que não é muito útil ( Alt-3 Alt-S iria inserir 3 espaços, a última palavra uma vez e aceitar a linha). Seria mais útil inserir a última palavra n th do último comando, ou a última palavra do n th último comando, ou as últimas n palavras do último comando.

Em zsh , em vez de usar uma macro, você poderia definir um novo widget. Por exemplo com:

use-last-word() {
  LBUFFER+=" "
  zle insert-last-word
  zle accept-line
}

zle -N use-last-word
bindkey '\es' use-last-word

Alt-3 Alt-S inseria a última palavra 3 rd do último comando.

Para inserir a última palavra do último comando rd :

use-last-word() { 
  LBUFFER+=" "
  local n=$NUMERIC
  unset NUMERIC
  repeat ${n:-1} zle insert-last-word
  zle accept-line
}

Para inserir as últimas 3 palavras do último comando:

use-last-word() { 
  for ((NUMERIC=${NUMERIC:-1}; NUMERIC; NUMERIC--)) {
    LBUFFER+=" "; zle insert-last-word
  }
  zle accept-line
}
    
por 26.05.2013 / 17:51
4

Sinto-me mal por responder à minha pergunta como esta, mas tenho uma solução:

pst() {
    [ $# = 0 ] && return 1

    if [ -n $ZSH_VERSION ]; then
        local read=vared
    else
        local read=read
    fi

    local cmd
    local -a args
    args=("$@")
    while $read -p '> ' cmd ; do
        test -z "$cmd" && continue
        $cmd "${args[@]}"
    done
}

Isso funciona assim:

$ pst 192.168.1.5
> nmap -Pn -sS
> ssh
> curl
> wget -r

Vou deixar a questão em aberto por um tempo para ver se alguma solução superior aparece. Uma grande desvantagem dessa solução é que os comandos que ela executa não estão registrados.

    
por 26.05.2013 / 16:04
1

Eu não implementei nada assim, mas gostaria de saber se você poderia aproveitar as duas facilidades oferecidas pelo shell. O $ PATH e o comando completo.

Quando você está no seu "modo especial" você poderia fornecer algo como a aba completa, mas ao invés de ter que repetidamente batê-lo, você digita algumas letras do comando atual que você quer rodar nm (para nmap) e um combo de teclas similar a tab que interrogaria o $ PATH procurando por executáveis que correspondam ao que você digitou até agora e então retornará uma lista para você assim:

eu digito:

$ pst 192.168.1.5
> nm <press SHIFT-TAB>

Recebi a seguinte lista:

1* - nmap 192.168.1.5    2 - nmap2 192.168.1.5    3 - nmap3 192.168.1.5

OBSERVAÇÃO: A lista acima seria o que correspondia ao que eu digitei ao interrogar o $PATH .

Na lista acima, eu poderia pressionar enter para aceitar a primeira resposta (1 *) ou digitar o número da correspondência que desejo usar:

>> 2 <press ENTER>

Você também pode integrar o recurso complete no bash e em outros shells para restringir as correspondências, de modo que apenas correspondências que possam aceitar os tipos de argumentos fornecidos para pst <arg> sejam consideradas na correspondência.

    
por 26.05.2013 / 17:28