Emular o comportamento de cortar e cortar o mouse em um script de teste

3

Eu tenho um shell script que gera comandos shell que devem ser copiados e colados com o mouse de uma janela de terminal para outra (eu posso testá-lo na mesma janela). A saída deve não conter nenhum espaço em branco significativo diferente de espaço simples, e as linhas de saída devem ser truncadas para que o código possa ser copiado adequadamente mesmo em terminais onde quebras de linha suaves são copiados como quebras de linha rígidas. Eu gostaria de ter certeza. Estou pensando em algo assim:

$ eval 'resize -s 24 80'
$ reset
$ my_script
$ mouse_copy *all of the terminal history except for the first line*
$ mouse_paste
$ assert *the paste created the proper result*

Emular isso com algo como xclip seria bom, se possível.

O script deve ser executado em um servidor Linux personalizado que não tenha X. Não sei em detalhes como a saída do terminal é enviada ao cliente, mas talvez o script tenha que perguntar ao servidor X no lado do cliente o que está sendo exibido atualmente?

    
por l0b0 05.07.2012 / 14:58

3 respostas

3

xsel - manipula a seleção X.

xsel --clipboard --input lê stdin na área de transferência

xsel --clipboard --output escreve conteúdo da área de transferência para stdout

    
por 05.07.2012 / 15:43
1

Aqui está um fragmento de shell (não testado) que deve fazer algo próximo do que você quer, pelo que entendi da sua pergunta.

set -e
# Collect the output of the script in a variable
script_output=$(my_script)
# Check that the script output is nice and copypastable
awk '
    /[^[:print:]]/ { print NR ": non-printable character"; exit 1 }
    / $/ { print NR ": trailing whitespace"; exit 1 }
    /.{79}/ { print NR ": line too long"; exit 1 }
' <<EOF
$script_output
EOF

# Use expect to spawn a shell, feed it the script output, and
# check the result against expectations
export script_output
expect <<'EOF'
spawn sh
send "[array get env script_output]\n"
expect "the proper result"
EOF
    
por 06.07.2012 / 02:55
0

Como eu entendi, você precisa reexecutar comandos exatamente na mesma sequência que você já fez desde o início da sessão. Certo?

Portanto, o comando history pode ser útil aqui. Na verdade, depende do seu HISTFORMAT , mas se tiver valor padrão, você pode usar algum comando de flag como echo SOME_FLAG e use:

history | sed -n 'H;/SOM_FLAG/{/history/!{x;d}};${x;s/\n\s\+[0-9]*\s\+/\n/g;p}'

que irá extrair os últimos comandos desde SOME_FLAG. Como sed funciona aqui:
H apenas copia o padrão atual para armazenar o buffer
/SOME_FLAG/ relógios se a seqüência de caracteres corresponde a SOME_FLAG
se isso acontecer, também verifica se ele não corresponde a history (ele também depende de seus shell stiings, às vezes o comando já está no histórico logo após a execução e histry verá sua entrada nele)
se corresponder a ele, exclua todas as entradas anteriores. e temos todos os comandos após o último sinalizador SOME_FLAG.

Depois disso, você pode enviá-lo para o shell via pipe, por exemplo:

history | sed -n 'H;/man/{/history/!{x;d}};${x;s/\n\s\+[0-9]*\s\+/\n/g;p}' | bash -x

Infelizmente, é um método bastante perigoso: caso você esteja usando alguns comandos com exclusão ou com a modificação de dados importantes, isso pode destruir algo. No entanto, o método com cópia e colagem automáticas com simulação de mouse pode causar danos semelhantes. Portanto, tenha cuidado ao usar isso.

E também precisa definir o sinalizador sempre que você precisar desse recurso.

    
por 05.07.2012 / 15:57