লিনাক্স স্ক্রিপ্টে টার্মিনালে ব্যবহারকারীর ইনপুট লুকানো


121

আমার কাছে নীচের মতো বাশ স্ক্রিপ্ট রয়েছে:

#!/bin/bash

echo "Please enter your username";
read username;

echo "Please enter your password";
read password;

আমি চাই যে যখন ব্যবহারকারী টার্মিনালে পাসওয়ার্ড টাইপ করেন, তখন এটি প্রদর্শিত হবে না (বা ******* এর মতো কিছু প্রদর্শিত হবে)। আমি কীভাবে এটি অর্জন করব?


2
কেবল বিভ্রান্তি রোধ করতে সাধারণ নোট: লিনাক্স ব্যবহারকারী নাম / পাসওয়ার্ডের সাথে এই ব্যবহারকারীর নাম / পাসওয়ার্ডের কিছুই করার নেই - আমি "পাসওয়ার্ড পড়ুন" এর সময় ব্যবহারকারী যে ডেটাটি টাইপ করেন তা লুকানোর জন্য আমি কেবল একটি উপায় খুঁজছি।

আমি *পাসওয়ার্ড টাইপ করার সময় আউটপুট দিয়ে অভিনবতা পেতে চাইলে তার জন্য আমি একটি আপডেট যুক্ত করেছি
সিয়েজএক্স

অনেক ধন্যবাদ. একটি প্রশ্ন যদি কেউ জানে - এটি কি স্বয়ংক্রিয়ভাবে এটি .Bash_history- এ যেতে বাধা দেবে?


2
আমি মনে করি না এটি হবে, bash_history কেবলমাত্র আপনার আদেশটি ক্যাপচার করে, আপনার কমান্ড চালানোর পরে কী ঘটে তা ক্যাপচার করে না।
Andreas Wong

উত্তর:


272

আপনার পাঠানো কলটিতে কেবল সরবরাহ সরবরাহ করুন:

$ read -s PASSWORD
$ echo $PASSWORD

9
আমি এইভাবে ভাল পছন্দ। আমি যদি আমার প্রতিদিনের সীমাটি না আঘাত করি তবে আমি আপনাকে ভোট দিয়ে দেব
সিজেএক্সএক্স

4
প্রসঙ্গ সরবরাহ করতে: ইনপুট টাইপ করার সময় কিছুই-s প্রদর্শন করে না । ( -sএকটি নন-পসিক্স এক্সটেনশন, সুতরাং সমস্ত শেল এটি সমর্থন করে না, যেমন ashবুসিবক্সের সাথে আসা শেল; ssty -echoযেমন শেলগুলিতে
এপ্রোচটি

3
@ ইলেক্ট্রন পৃষ্ঠায় কিছুই নেই এমনটি manপ্রস্তাব দেয় যা -sপাঠ্য রঙকে পটভূমির রঙের মতোই সেট করে। এটি কেবল "নীরবে প্রতিধ্বনিত"। ss64.com/bash/read.html Silent mode. If input is coming from a terminal, characters are not echoed.
Andreas Wong

2
@ ইলেক্ট্রন আমি আমার বাক্সে পরীক্ষা করেছিলাম, এটি কেবল কার্সরকে সরিয়ে দেয় না, যখন আমি আমার পাসওয়ার্ডে যে টাইপটি লিখেছিলাম সেখানে হাইলাইট করার চেষ্টা করি, পরে আমি এটি পেস্ট করতে পারি না বলে মনে হয়। বই যা বলে তা সত্য হলে উভয়েরই হওয়া উচিত। আমি অনুমান করছি শেলটির অন্যরকম স্বাদ পাবেন (আমি ব্যাশ ৪.১.২ (১) ব্যবহার করছিলাম)।
আন্দ্রেস ওয়াং

1
@ ডোমিনিকাস মোস্তৌসকিস হ্যাঁ তবে লেবেল বাশের জন্য, সুতরাং সমাধানটি। অনেকগুলি শেল বৈকল্পিক রয়েছে যেখানে এটি কাজ করে না :)
আন্দ্রেস ওয়াং

25

হালনাগাদ

আপনি যে *টাইপের প্রতিটি চরিত্রের জন্য আউটপুট তৈরি করে অভিনবতা পেতে চান সে ক্ষেত্রে আপনি এ জাতীয় কিছু করতে পারেন (অ্যান্ড্রিয়াসের read -sসমাধান ব্যবহার করে ):

unset password;
while IFS= read -r -s -n1 pass; do
  if [[ -z $pass ]]; then
     echo
     break
  else
     echo -n '*'
     password+=$pass
  fi
done

অভিনব না হয়ে

echo "Please enter your username";
read username;

echo "Please enter your password";
stty -echo
read password;
stty echo

এটি হবে IFS=$'\n'আসলে আপনি করতে পারেন যাতে শেষ পাসওয়ার্ড লেখা। অন্যথায় সুন্দর; খুব চালাক.
sorpigal

2
সেট করার দরকার নেই IFS=$'\n'কারণ পড়ার ডিফল্ট ডিলিমিটার -d $'\n'। যদি নুল স্ট্রিংয়ের উপর ভাঙার জন্য-এ-স্টেটমেন্ট হয়, যা একটি নতুন লাইনে ঘটে থাকে, যা তাদের পাসওয়ার্ড শেষ করতে দেয়।
সিজিএক্সএক্স

ফ্রিবিএসডি-তে বাশ 3.x দিয়ে পরীক্ষায় আমি এটি দেখতে পাচ্ছি না। 3.1.17 দিয়ে লিনাক্সে পরীক্ষা করা আপনার ফলাফল দেয় yield আমি এই মুহুর্তে কোনও বিএসডি বক্স হাতে পাইনি তবে আমি নিজের কৌতুহলের জন্যই আগামীকাল এটি নিশ্চিত করার চেষ্টা করব।
sorpigal

@ সরপিগল: আকর্ষণীয়, আপনি কী সন্ধান করেছেন তা আমাকে জানান। আমি সবই বহনযোগ্যতার বিষয়ে
সিজেএক্স

2
আমি এইটা পাইছি. আমার ফ্রিবিএসডি পরীক্ষাটি আপনার লেসমানার পোস্টের মূল ভুল সম্পাদনা থেকে অনুলিপি করা ও কোড করা কোডের উপর ভিত্তি করে তৈরি হয়েছিল, যার মধ্যে একটি গুরুত্বপূর্ণ পার্থক্য রয়েছে: আপনি readএকটি পাস করছিলেন -d ''। আমি যখন লিনাক্সে পরে এটি পুনরায় চেষ্টা করেছি তখন আমি পুনরায় পোস্ট করা সংস্করণটি ব্যবহার করেছি। যদি আমি -d ''অবশ্যই বাদ দেওয়ার চেষ্টা করি এটি ফ্রিবিএসডি-তে অভিন্নভাবে কাজ করে! আমি আসলে বেশ স্বস্তি পেয়েছি যে এখানে কোনও রহস্যময় প্ল্যাটফর্ম যাদু নেই।
sorpigal

17

এমন কোনও সমাধানের জন্য যা বাশ ছাড়াই কাজ করে বা readআপনার কাছ থেকে কিছু বৈশিষ্ট্য sttyপ্রতিধ্বনি অক্ষম করতে ব্যবহার করতে পারে

stty_orig=$(stty -g)
stty -echo
read password
stty $stty_orig

9

এখানে যোগ করা হয়েছে ব্যাকস্পেসের সমর্থনের জন্য @ সিয়েজএক্সের দুর্দান্ত- *প্রিন্টিং সমাধানের একটি বৈচিত্র ; এটি ব্যবহারকারীকে কী ( ম্যাকের কী) দিয়ে তাদের এন্ট্রি সংশোধন করতে দেয় , সাধারণত পাসওয়ার্ডের অনুরোধগুলির দ্বারা সমর্থিত:bash backspacedelete

#!/usr/bin/env bash

password=''
while IFS= read -r -s -n1 char; do
  [[ -z $char ]] && { printf '\n'; break; } # ENTER pressed; output \n and break.
  if [[ $char == $'\x7f' ]]; then # backspace was pressed
      # Remove last char from output variable.
      [[ -n $password ]] && password=${password%?}
      # Erase '*' to the left.
      printf '\b \b' 
  else
    # Add typed char to output variable.
    password+=$char
    # Print '*' in its stead.
    printf '*'
  fi
done

বিঃদ্রঃ:

  • ব্যাকস্পেস রেকর্ড অক্ষর কোড কেন 0x7fটিপছে: "আধুনিক সিস্টেমে ব্যাকস্পেস কীটি প্রায়শই মুছে ফেলা অক্ষরটিকে (ASCII বা ইউনিকোডে 0x7f) ম্যাপ করা হয়" https://en.wikedia.org/wiki/Backspace
  • \b \bবামে চরিত্রটি মোছার চেহারা দেওয়ার জন্য প্রয়োজন ; \bকার্সারটি কেবল বাম দিকে সরানো ব্যবহার করে অক্ষরটিকে অক্ষত রাখে ( ননডস্ট্রস্ট্রাকটিভ ব্যাকস্পেস)। কোনও স্থান মুদ্রণ করে এবং আবার ফিরে যাওয়ার মাধ্যমে, চরিত্রটি মুছে ফেলা হয়েছে বলে মনে হয় (ধন্যবাদ, "ব্যাকস্পেস" অব্যাহতি চরিত্র '\ বি' তে সি, অপ্রত্যাশিত আচরণ? )।

একটি POSIX শুধুমাত্র শেল (যেমন, shউবুন্টু এবং ডেবিয়ান, যেখানে উপর shহয় dash), ব্যবহার stty -echoপদ্ধতির (যা দরুণ পর্যাপ্ত কারণ এটি ছাপে কিছুই ), কারণ readbuiltin সমর্থন করবে না -sএবং -nঅপশন।


ধন্যবাদ, ডিলান আমি কেবল বুঝতে পেরেছি যে এখন পর্যন্ত টাইপ করা পাসওয়ার্ড থেকে শেষ চরিত্রটি সরিয়ে দেওয়ার কোডটি সরল করা যায় - আপডেট দেখুন।
mklement0

3

@ লেসমানার উত্তর থেকে কিছুটা আলাদা (তবে বেশিরভাগের মত)

stty -echo
read password
stty echo

সহজভাবে: লুকান প্রতিধ্বনি আপনার জিনিস প্রতিধ্বনি প্রদর্শন


@ লেসমানার উত্তরের চেয়ে কেন এটি ভাল তা আপনি ব্যাখ্যা করতে পারেন ? আমি দেখতে পাই এটি অন্য sttyকলের জন্য কম ওভারহেড সহ সহজ , এবং স্ট্যাকের মধ্যে একটি কম ভেরিয়েবল - কেবল প্রতিধ্বনি দূরে নিয়েছে এবং কেবল প্রতিধ্বনি পুনরুদ্ধার করবে। এটির অন্যান্য sttyসেটিংসকে বিপর্যস্ত করার কোনও সম্ভাব্য উপায় কি ? লেসমানার সমস্ত সেটিংস সংরক্ষণ করে।
জেফ পেকেট 19

2

এখানে @ সিজেএক্সএক্সের উত্তরের একটি প্রকরণ রয়েছে যা প্রচলিত বোর্ন শেল (যাতে +=কার্যভারের কোনও সমর্থন নেই ) নিয়ে কাজ করে।

password=''
while IFS= read -r -s -n1 pass; do
  if [ -z "$pass" ]; then
     echo
     break
  else
     printf '*'
     password="$password$pass"
  fi
done

একটি traditionalতিহ্যবাহী বোর্ন শেল (বা একটি পসিক্স-কমপ্লায়েন্ট এক) এছাড়াও স্বীকৃতি দেয় না এবং [[ ... ]]এর readবিল্টইনটিতে বিকল্পগুলি -sএবং -nবিকল্পগুলিও থাকবে না । আপনার কোডটি dashউদাহরণস্বরূপ কাজ করবে না । (এটা প্ল্যাটফর্মের যেখানে কাজ করবে shআসলে bash, এই ধরনের ওএসএক্স, যেখানে হিসাবে bashযখন প্রার্থনা যেমন shনিছক কয়েক ডিফল্ট বিকল্পসমূহ পরিবর্তন এখনও সবচেয়ে bashisms সমর্থনকারী।)
mklement0

2
প্রতিক্রিয়ার জন্য ধন্যবাদ, একককে পরিবর্তন করা হয়েছে [তবে আপনার readবিকল্পগুলির অভাব থাকলে স্পষ্টতই আমি বেশি কিছু করতে পারি না ।
ট্রিপলি

2

আমি সবসময় আনসি পলায়ন চরিত্রগুলি ব্যবহার করতে চাই:

echo -e "Enter your password: \x1B[8m"
echo -e "\x1B[0m"

8mপাঠ্যটিকে অদৃশ্য করে তোলে এবং 0mপাঠ্যটিকে "স্বাভাবিক" এ পুনরায় সেট করে। এটি আনসিকে পলায়ন করা সম্ভব করে তোলে।

একমাত্র সতর্কতা হ'ল আপনি এখনও সেখানে থাকা পাঠ্যটি অনুলিপি করে আটকে দিতে পারেন, তাই আপনি যদি সত্যিই সুরক্ষা চান তবে আপনার সম্ভবত এটি ব্যবহার করা উচিত নয়।

এটি যখন লোকেরা টাইপ করে তখন কেবল আপনার পাসওয়ার্ডগুলিকে তাকাতে দেয় না Just পরে আপনার কম্পিউটারটি রেখে যাবেন না। :)


বিঃদ্রঃ:

উপরেরটি প্ল্যাটফর্মটি স্বতন্ত্র যতক্ষণ না এটি আনসি অব্যাহত ক্রমগুলি সমর্থন করে।

তবে, অন্য ইউনিক্স সমাধানের জন্য, আপনি কেবল readঅক্ষরগুলি প্রতিধ্বনিত না করতে বলতে পারেন ...

printf "password: "
let pass $(read -s)
printf "\nhey everyone, the password the user just entered is $pass\n"

1

ব্যবহারকারীর নাম এবং পাসওয়ার্ড পান

এটি পড়ার জন্য আরও পরিষ্কার করুন তবে এটিকে স্ক্রিনের থেকে আরও ভাল অবস্থানে রাখুন

#!/bin/bash
clear
echo 
echo 
echo
counter=0
unset username
prompt="  Enter Username:"
while IFS= read -p "$prompt" -r -s -n 1 char
do
    if [[ $char == $'\0' ]]; then
        break
    elif [ $char == $'\x08' ] && [ $counter -gt 0 ]; then
        prompt=$'\b \b'
        username="${username%?}"
        counter=$((counter-1))
    elif [ $char == $'\x08' ] && [ $counter -lt 1 ]; then
        prompt=''
        continue
    else
        counter=$((counter+1))
        prompt="$char"
        username+="$char"
    fi
done
echo
unset password
prompt="  Enter Password:"
while IFS= read -p "$prompt" -r -s -n 1 char
do
    if [[ $char == $'\0' ]]; then
        break
    elif [ $char == $'\x08' ] && [ $counter -gt 0 ]; then
        prompt=$'\b \b'
        password="${password%?}"
        counter=$((counter-1))
    elif [ $char == $'\x08' ] && [ $counter -lt 1 ]; then
        echo
        prompt="  Enter Password:"
        continue
    else
        counter=$((counter+1))
        prompt='*'
        password+="$char"
    fi
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.