Bash - Dividir os parâmetros dos comandos anteriores

2

Como alguém poderia analisar o comando anterior no bash?

Exemplo:

root$ ssh [email protected]
root$ echo !$ &>/tmp/foo.txt
root$ cat /tmp/foo.txt
[email protected]

Meta:
Envie apenas o ipaddress 1.2.3.4 para foo.txt

Eu tentei usar o awk, mas não encontrei sucesso

#doesn't work
cat /tmp/foo.txt |awk '{print $2,$3,$4}' 

Eu também tentei analisar apenas os dígitos usando sed

#doesn't work
sed 's/.//p' /tmp/foo.txt 
sed 's/[0-9]//p' /tmp/foo.txt

Considerações
1.2.3.4 será sempre um número entre 0.0.0.0 e 255.255.255.255
O nome de usuário foo pode ser qualquer tamanho
[email protected] é não necessariamente o único parâmetro passado para ssh (eg .. ssh 1.2.3.4 -l foo)

Recursos
link
link
link

Atualizar
Mais esclarecimentos
O objetivo final será criar uma função no meu .bashrc que me permita remover facilmente uma chave ssh conflitante.

root$ ssh [email protected]  
#some big error message warning about man in the middle attack
root$ ssh-keygen -R 1.2.3.4
    
por spuder 22.07.2013 / 20:03

6 respostas

5

Com sua sintaxe original: $ cat /tmp/foo.txt | awk -F@ '{print $2}' e 1.2.3.4

    
por 22.07.2013 / 20:28
1

Se você puder usar outra sintaxe para o comando ssh, será mais fácil:

ssh -l foo 1.2.3.4 
echo !:3 

mas isso requer essa sintaxe exata.

    
por 22.07.2013 / 20:15
0

Você pode usar !! para acessar a linha de comando anterior, então

echo !! | sed 's/.*@\(.*\).*//' | awk '{print $1}'

pode funcionar para você, por exemplo,

echo ssh [email protected] ls | ...
123.456.654.321

echo ssh -p 19111 [email protected] | ...
123.456.654.321

A única suposição aqui é que o ipaddress será precedido por um @ e que há um espaço ou fim de linha após ele.

    
por 22.07.2013 / 20:17
0

Quando você imprime a saída em um arquivo, usarei o Perl:

cat /tmp/foo.txt | \
perl -ne ' print $& if $_ =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/'
    
por 22.07.2013 / 20:22
0

Para encontrar um endereço IP numérico do comando ssh anterior:

echo $(grep -oP '\d+\.\d+\.\d+\.\d+' <<< "!ssh")

Não vejo nada no manual que permita encontrar "um argumento que corresponda a um padrão" ( link )

Certifique-se de que não é possível colocar expansões de histórico em estilo ! dentro de uma função, mas há o comando fc :

# return the IP address of the most recent ssh command
sship () { command grep -oP '\d+\.\d+\.\d+\.\d+' < <(fc -l ssh); }

Isso não obriga você a ter o endereço IP como um argumento específico (por exemplo, o último)

ssh [email protected] hostname
    
por 22.07.2013 / 20:25
0

Não há uma construção de expansão de histórico para quebrar em @ . No entanto, o último argumento do comando anterior também está disponível como a variável $_ .

ssh-keygen -R "${_##*@}"

Observe que isso só funciona se o nome do host for o último argumento do comando anterior: não funcionará se o comando anterior for, por exemplo, %código%. Você pode tentar analisar a saída de ssh somehost ls para extrair o primeiro argumento não-opcional.

Seu objetivo me parece uma idéia ruim. É raro precisar remover uma chave de host SSH - basicamente, isso só deve acontecer se a máquina tiver sido reinstalada. Se você precisar fazer isso com frequência, algo está errado com sua metodologia, ou talvez com sua configuração de rede (certifique-se de que seus clientes DHCP obtenham endereços IP reproduzíveis, a menos que você nunca se conecte a eles de outra máquina).

    
por 23.07.2013 / 04:04