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
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?
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
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
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.
Tags mouse terminal copy-paste