用shell实现一个“输入密码”程序

在写安装程序免不了要输入密码一类的,c里比较直白,getchar()加printf()一想就可以了,具体的逻辑实现也不会多难。可是在shell这种限制性语言里可没那么简单了,比如你想下输入命令read,怎么能只读入一个字符就退出呢?

于是我上网搜了搜,改了改,感兴趣的不如一起来学习下。

 getchar() {
      stty cbreak 
-echo
      
if=/dev/tty bs=1 count=1 2> /dev/null
      stty 
-cbreak echo
           }
while : ; do
  ret
=`getchar`
  
case "$ret" in
    ^H) str
=$(echo $str|sed 's/.$//')
       echo 
-ne "\b \b"
       ;;
    
""break;
       ;;      
    
*) str="$str$ret"
        echo 
-"*"
    esac
done

 

getchar()函数就仿c语言的自己做了一个,每次输入一个字符就退出。

具体的stty的设置可以自己man,这里第一行设置了“击一下键盘输入一个字符就会响应,而不是等到输入回车按行响应”。第三行恢复设置。第二行dd是个linux命令:

dd命令:
功能说明:读取,转换并输出数据。

语  法:dd [bs=<字节数>][cbs=<字节数>][conv=<关键字>][count=<区块数>][ibs=<字节数>][if=<文件>][obs=<字节数>][of=<文件>][seek=<区块数>][skip=<区块数>][--help][--version]

补充说明:dd可从标准输入或文件读取数据,依指定的格式来转换数据,再输出到文件,设备或标准输出。

参  数:
  bs=<字节数>   将ibs( 输入)与obs(输出)设成指定的字节数。
  cbs=<字节数>   转换时,每次只转换指定的字节数。
  conv=<关键字>   指定文件转换的方式。
  count=<区块数>   仅读取指定的区块数。
  ibs=<字节数>   每次读取的字节数。
  if=<文件>   从文件读取。
  obs=<字节数>   每次输出的字节数。
  of=<文件>   输出到文件。
  seek=<区块数>   一开始输出时,跳过指定的区块数。
  skip=<区块数>   一开始读取时,跳过指定的区块数。
  --help   帮助。
  --version   显示版本信息。

 


 

 主程序包含了一个while循环来使你不断输入密码。

 ret=`getchar` #取出输入的值放到ret变量里。这里你需要了解``和$()的意思。

然后根据ret的值来相应的处理:

^H代表backspace。为什么要对退格键进行特殊处理呢,你可以试一下,如果不特殊处理的话是不能发挥退格的功效的。为什么不能发挥退格的功效呢,那是因为此时处于raw mode下,而非cooked mode下。精彩的就在特殊处理的部分,需要清楚的是所谓的特殊处理就是“删除输入backspace代表的字符(在raw模式下backpace键输入的是^H),删除一个*号” echo $str|sed 's/.$//   $代表最后一行,echo $str最后一行就是换行。.$就是倒数第二行最后一个字符(即str最后一个字符^H)。。替换成空就完成了“删除输入backspace代表的字符”,然后在echo "\b"删除一个*号就OK了。。。

在此不得不感叹一下linux下这些命令功能的强大,聊聊两句想实现什么功能实现什么功能,再感叹设计者的强大。

然后输入为空(回车)时退出循环,其他情况都是密码显示*号。

 

 

posted @ 2009-11-23 10:12  dmesg  阅读(1332)  评论(0编辑  收藏  举报