teste de eco | stty -echo -> stty: entrada padrão: ioctl inadequado para dispositivo

9

Eu estava jogando com um script perl que recebe a entrada do usuário com o seguinte:

system( qw( stty -echo ) );
$? == 0 or die "Error unable to disable character printing.\n";
print "$prompt: ";
my $input = <STDIN>;

Eu pensei que seria capaz de canalizar uma resposta usando eco, no entanto, parece entrar em conflito com o comando stty -echo e produz o seguinte erro:

stty: standard input: Inappropriate ioctl for device

Sem alterar o script perl, o que poderia ser feito no bash para passar na entrada? O que causa o problema?

user2219808
fonte
em vez de perl use o expectator intérprete: como: thegeekstuff.com/2010/10/expect-examples
PersianGulf
O exemplo perl pode não estar destacando o problema. O erro surge essencialmente desta sequência: teste de eco | stty -echo;
user2219808

Respostas:

5

stty -echoaltera as configurações no descritor do arquivo de entrada. Se você estiver canalizando algo para o comando stty, o descritor do arquivo de entrada é o pipe, e stty em um pipe é, eh, inapropriado (como a mensagem de erro diz).

Não está claro o que você está tentando alcançar. Se você deseja enviar o texto testpara o seu script perl para ser lido na my $input = <STDIN>;linha, basta se livrar das coisas stty.

Se você também quiser ler o texto como entrada do usuário (digitado) e, ao fazê-lo, impedir que o texto seja ecoado (por exemplo, uma senha), teste se a entrada padrão é um tty (terminal) antes de executar o stty:

system( qw( stty -echo ) ) if -t 0;

Dito isto, não concorde com todos os tipos de coisas, não é para isso que serve o perl (caso contrário, você também pode escrever tudo no shell). Você pode alterar as configurações stty de dentro do perl, o google é seu amigo.

Wurtel
fonte
Não era meu script, então eu estava procurando maneiras de passar informações e automatizá-las sem alterá-las. Esperar é provavelmente a solução, eu pensei que poderia ter sido uma outra maneira de coisas de tubos em.
user2219808
system( qw( stty -echo < /dev/tty) );é uma solução possível, mas o script precisa restaurar o eco posteriormente. Usar expect pode ser um ajuste melhor.
Henk Langeveld
2

sttyconecta ao terminal em sua entrada padrão. Você precisa executar o script Perl com sua entrada padrão conectada ao terminal em que deseja atuar. Se o próprio script Perl for chamado de um escopo em que a entrada padrão é redirecionada para algo diferente do terminal, você pode usar /dev/ttypara se referir ao terminal de controle do processo:

that_perl_script </dev/tty

Se você deseja passar a entrada para o script e não se importa com o que o script faz com as configurações do terminal, você pode usar expect . O uso de expect para alimentar uma senha com um comando que requer um terminal é comum.

Se o script Perl acessar o terminal apenas chamando o sttycomando, uma abordagem alternativa seria fornecer um sttycomando fictício .

mkdir dummy-stty
echo '#!/bin/sh' >dummy-stty/stty
chmod a+rx dummy-stty/stty
echo swordfish | PATH=$PWD/dummy-stty:$PATH that_perl_script
Gilles 'SO- parar de ser mau'
fonte