78 votes

Comment cacher la saisie du mot de passe dans le terminal en ruby script.

Je suis novice en ruby. J'ai besoin de recevoir un mot de passe en entrée par gets commandement.

Comment masquer l'entrée du mot de passe tapé dans le terminal, pendant gets appelez

0 votes

183voto

eclectic923 Points 931

On peut aussi utiliser le core ruby.

$ ri IO.noecho

 (from ruby core)
 ------------------------------------------------------------------------------
   io.noecho {|io| }
  ------------------------------------------------------------------------------

 Yields self with disabling echo back.

   STDIN.noecho(&:gets)

 will read and return a line without echo back.

Pour la version 1.9.3 (et les versions supérieures), cela nécessite d'ajouter require 'io/console' à votre code.

require 'io/console'
text = STDIN.noecho(&:gets)

21 votes

Pour la version 1.9.3, cela nécessite l'ajout de require 'io/console' à votre code. Bien mieux que n'importe quelle option de gemme habituellement.

1 votes

Je ne saurais trop insister sur cette réponse. C'est toujours mieux que d'avoir à inclure des gemmes supplémentaires !

20 votes

N'oubliez pas de .chomp votre entrée ! pass = STDIN.noecho(&:gets).chomp

30voto

Otto Allmendinger Points 11853

Il existe une bibliothèque appelée highline qui fonctionne comme suit :

require 'rubygems'
require 'highline/import'

password = ask("Enter password: ") { |q| q.echo = false }
# do stuff with password

24voto

ghostdog74 Points 86060

Meilleure méthode à partir de la réponse de @eclectic923 :

require 'io/console'
password = STDIN.noecho(&:gets).chomp

Pour la version 1.9.3 (et les versions supérieures), cela nécessite d'ajouter require 'io/console' à votre code.

Réponse originale :

Ruby " Mot de passe "est une autre alternative.

0 votes

Merci, c'est exactement ce que je cherchais.

10 votes

Cette réponse devrait être dépréciée en faveur de la solution ruby de base de @eclectic923.

16voto

Charles Points 2878

Comme les autres l'ont mentionné, vous pouvez utiliser IO#noecho pour Ruby >= 1.9. Si vous souhaitez bénéficier du support pour la version 1.8, vous pouvez vous rendre sur le site du read fonction shell intégrée :

begin
  require 'io/console'
rescue LoadError
end

if STDIN.respond_to?(:noecho)
  def get_password(prompt="Password: ")
    print prompt
    STDIN.noecho(&:gets).chomp
  end
else
  def get_password(prompt="Password: ")
    `read -s -p "#{prompt}" password; echo $password`.chomp
  end
end

Maintenant, obtenir un mot de passe est aussi simple que :

@password = get_password("Enter your password here: ")

Note : Dans l'implémentation utilisant read ci-dessus, vous rencontrerez des difficultés si vous (ou un autre client de get_password ) transmet les caractères spéciaux de l'interpréteur de commandes dans l'invite (par ex. $ / " / ' /etc). Idéalement, vous devriez échapper la chaîne d'invite avant de la transmettre à l'interpréteur de commandes. Malheureusement, Shellwords n'est pas disponible dans Ruby 1.8. Heureusement, il est facile de backport des bits pertinents vous-même (en particulier shellescape ). Avec cela, vous pouvez faire cette légère modification :

  def get_password(prompt="Password: ")
    `read -s -p #{Shellwords.shellescape(prompt)} password; echo $password`.chomp
  end

J'ai mentionné quelques problèmes avec l'utilisation de read -s -p dans un commentaire ci-dessous :

Eh bien, le cas de la version 1.8 est un peu bizarre ; il n'autorise pas les barres obliques inversées à moins que vous n'appuyiez deux fois sur la touche backslash. backslashes, à moins que vous n'appuyiez deux fois sur backslash : "Le caractère backslash `\' peut être utilisé pour supprimer toute signification spéciale pour le prochain caractère lu et pour la continuation de la ligne." Aussi : "Les caractères dans la valeur de la variable IFS sont utilisés pour diviser la ligne en mots. "Cela devrait probablement bien pour la plupart des petits scripts, mais vous voudrez probablement quelque chose de plus robuste pour les applications plus importantes.

Nous pouvons résoudre certains de ces problèmes en retroussant nos manches et en faisant le plus difficile. stty(1) . Un aperçu de ce que nous devons faire :

  • Mémoriser les paramètres actuels du terminal
  • Tour de l'écho
  • Imprimer l'invite et obtenir l'entrée de l'utilisateur
  • Restaurer les paramètres du terminal

Nous devons également veiller à restaurer les paramètres du terminal lorsqu'il est interrompu par des signaux et/ou des exceptions. Le code suivant traitera correctement les signaux de contrôle du travail (SIGINT/SIGTSTP/SIGCONT) tout en jouant gentiment avec les gestionnaires de signaux existants :

require 'shellwords'
def get_password(prompt="Password: ")
  new_sigint = new_sigtstp = new_sigcont = nil
  old_sigint = old_sigtstp = old_sigcont = nil

  # save the current terminal configuration
  term = `stty -g`.chomp
  # turn of character echo
  `stty -echo`

  new_sigint = Proc.new do
    `stty #{term.shellescape}`
    trap("SIGINT",  old_sigint)
    Process.kill("SIGINT", Process.pid)
  end

  new_sigtstp = Proc.new do
    `stty #{term.shellescape}`
    trap("SIGCONT", new_sigcont)
    trap("SIGTSTP", old_sigtstp)
    Process.kill("SIGTSTP", Process.pid)
  end

  new_sigcont = Proc.new do
    `stty -echo`
    trap("SIGCONT", old_sigcont)
    trap("SIGTSTP", new_sigtstp)
    Process.kill("SIGCONT", Process.pid)
  end

  # set all signal handlers
  old_sigint  = trap("SIGINT",  new_sigint)  || "DEFAULT"
  old_sigtstp = trap("SIGTSTP", new_sigtstp) || "DEFAULT"
  old_sigcont = trap("SIGCONT", new_sigcont) || "DEFAULT"

  print prompt
  password = STDIN.gets.chomp
  puts

  password
ensure
  # restore term and handlers
  `stty #{term.shellescape}`

  trap("SIGINT",  old_sigint)
  trap("SIGTSTP", old_sigtstp)
  trap("SIGCONT", old_sigcont)
end

0 votes

Le cas de la version 1.8 est un peu bizarre ; il n'autorise pas les barres obliques inversées, à moins que vous n'appuyiez deux fois sur la barre oblique inversée : "Le caractère oblique inversé `\' peut être utilisé pour supprimer toute signification spéciale pour le prochain caractère lu et pour la continuation de la ligne." Aussi : "Les caractères de la valeur de la variable IFS sont utilisés pour diviser la ligne en mots. "Cela devrait probablement convenir à la plupart des petits scripts, mais vous voudrez probablement quelque chose de plus robuste pour les applications plus importantes.

5voto

Rishi Points 95

Pour ruby version 1.8 (ou Ruby < 1.9) j'ai utilisé lire comme mentionné par @Charles.

En plaçant le code qui est juste assez pour demander le nom d'utilisateur et le mot de passe, où le nom d'utilisateur sera répercuté à l'écran pendant la saisie, mais le mot de passe saisi sera silencieux.

 userid = `read -p "User Name: " uid; echo $uid`.chomp
 passwd = `read -s -p "Password: " password; echo $password`.chomp

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X