test d'écho | stty -echo -> stty: entrée standard: ioctl inapproprié pour le périphérique

9

Je jouais avec un script Perl qui accepte les entrées utilisateur avec les éléments suivants:

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

J'ai pensé que je serais capable de diriger une réponse en utilisant echo, mais cela semble entrer en conflit avec la commande stty -echo et produit l'erreur suivante:

stty: standard input: Inappropriate ioctl for device

Sans changer le script perl, que pourrait-on faire en bash pour passer l'entrée? Qu'est-ce qui cause le problème?

user2219808
la source
au lieu d'utiliser Perl interprète Attendez -vous : tels que: thegeekstuff.com/2010/10/expect-examples
Golfe Persique
L'exemple perl peut ne pas mettre en évidence le problème. L'erreur provient essentiellement de cette séquence: test d'écho | stty -echo;
user2219808

Réponses:

5

stty -echomodifie les paramètres du descripteur de fichier d'entrée. Si vous redirigez quelque chose vers la commande stty, alors le descripteur du fichier d'entrée est le canal, et stty sur un canal est, eh, inapproprié (comme le dit le message d'erreur).

On ne sait pas exactement ce que vous essayez de réaliser. Si vous voulez envoyer le texte testà votre script perl pour qu'il soit lu dans la my $input = <STDIN>;ligne, alors débarrassez-vous simplement des choses stty.

Si vous souhaitez également lire le texte en tant qu'entrée utilisateur (c'est-à-dire tapé) et éviter de faire écho au texte (par exemple un mot de passe), testez si l'entrée standard est un tty (terminal) avant de faire le stty:

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

Cela dit, ne pas débourser pour toutes sortes de choses, ce n'est pas à ça que sert perl (sinon vous pourriez aussi bien écrire le tout en shell). Vous pouvez modifier les paramètres stty depuis Perl, Google est votre ami.

gémir
la source
Ce n'était pas mon script, donc je cherchais des moyens de passer les entrées et de les automatiser sans les changer. Attendre est probablement la solution, je pensais qu'il y avait peut-être une autre façon de diriger les choses.
user2219808
system( qw( stty -echo < /dev/tty) );est une solution de contournement possible, mais le script doit ensuite restaurer l'écho. Utiliser expect peut être un meilleur choix.
Henk Langeveld
2

sttyse connecte au terminal sur son entrée standard. Vous devez exécuter le script Perl avec son entrée standard connectée au terminal sur lequel vous souhaitez agir. Si le script Perl est lui-même invoqué depuis une étendue où l'entrée standard est redirigée vers autre chose que le terminal, vous pouvez utiliser /dev/ttypour faire référence au terminal de contrôle du processus:

that_perl_script </dev/tty

Si vous voulez pouvoir transmettre des entrées au script et que vous ne vous souciez pas de ce que le script fait avec les paramètres du terminal, vous pouvez utiliser expect . L'utilisation de s'attendre à fournir un mot de passe à une commande qui nécessite un terminal est courante.

Si le script Perl accède uniquement au terminal en appelant la sttycommande, une approche alternative serait de fournir une sttycommande factice .

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- arrête d'être méchant'
la source