酷!學園
技術討論區 => 程式討論版 => 主題作者是: 任 於 2002-06-05 13:15
-
正在嘗試寫一些有用的 Bash Shell 但除了用 read 指令外
若要不按Enter就得到按鍵內容,有什麼語法可以達到目的!
或者非要改用Perl來寫
-
我知道C可以,
而且學生的作業就有了...
-
謝謝duncanlo
下午去查Perl,直譯式Perl下的getc也一樣,書上寫了一個代用例,
透過/dev/stty的特殊作法,可惜沒有多作解釋。真的沒有工具可以用嗎?
用C語言?在Linux還不知要從何開始哩......更何況連 bash, php,
MySQL, Perl都還不透澈,真的有點好高騖遠!如果子程序的變數不能回傳給父程序。
光用c寫個小工具也一樣不行,dos那套做法不管用了。
-
再問一次,你是要抓User按的鍵嗎?
我看看我學生時代的作業可不可以在Linux上用!
-
我是想做出類似dos下的簡單選單
while
[.....]
echo "1. .... # redraw the menu
echo "2. ....
....
echo "enter your chioce....:"
read press # read user's enter
do
case $press
1)
程序一
;;
2)
程序二
;;
......
......
esac
done
可惜一定要多按下Enter才能回應,如果不用按Enter就能立即回應似乎會順暢一點
-
接enter才能確認吧!
你這東東用shell寫就可以了...
-
所以說是Shell 梆死了!所有的工具選單都不能設快鍵直接啟動囉?
或者有任何取得快鍵的方法,就像在vi下設Macro一樣。
或者有什麼方法可以直接從裝置取得事件?
-
這是我從網上找到的解法, 在 REDHAT 7.2 上跑沒有問題...
getc()
{
stty raw
eval $1='`dd bs=1 count=1 2>/dev/null`'
stty cooked
}
echo "press a key"
getc ans
echo "this is you type:"
echo $ans
echo "bye !"
-
記得一個月前在新聞組上就有人問過類似的問題。雖然我對 programing 不在行﹐但我有一個‘不良習慣’--- 貪心﹗發現別人的好東西﹐都後先抓下來再說。剛纔翻了一下﹐找到如下這段﹕
---------
"小州" <kenduest.bbs@bbs.sayya.org> 撰寫於郵件 news:40FeJR$6yN@bbs.sayya.org...
> ※ 引述《bm2fun.bbs@bbs.ntu.edu.tw (The Magic Word is D3)》之銘言:
> > 剛剛在幫朋友改一個shell script,就是那種標準用
> > read讀入字串然後作判斷的選單,突然想到用者種方式每次都要按
> > Enter後才能執行選項,而shell script是否能像C語言的getche()函數一樣直接
> > 抓一個鍵後不用按Enter就執行選項呢?
>
> 但是 getch、getche 不是 ansi c 的 function ....
>
> 剛剛用 google 找到一篇文章的內容有提到方式。
>
> #!/bin/sh
>
> echo "Enter a keystroke"
> oldstty=`stty -g`
> stty -icanon -echo min 1 time 0
> key=`dd bs=4 count=1 <&0 2>/dev/null`
> stty $oldstty
> echo "key is" $key
---------
至於 bash 中的 read ﹐只所以要等 CR 字符﹐是因為 read 可以讀入多個字母做變數值﹐也能一次讀入多個變數值的緣故﹐例如﹕
echo -n "what is your full name: "
read FName LName
echo "Your fistname is $FNanem, and your lastname is $LName."
-
謝謝netman大哥及jeffer兄的解答:
實做後發現有點小問題
getc()
{
stty raw
eval $1='`dd bs=1 count=1 2>/dev/null`'
stty cooked
}
echo "press a key"
getc ans
echo "this is you type:"
echo $ans
echo "bye !"
無法關閉輸入鍵的回應
輸出如下:
#press a key
gthis is you type:
g
bye !
經過一番測試修正如下:
getc()
{
stty raw -echo
eval $1=`dd bs=1 count=1 2>/dev/null`
stty cooked echo
}
echo "press a key"
getc ans
echo "this is you type:"
echo $ans
echo "bye!"
大致正常了,但是如果按下的是兩碼的功能鍵還是有Bug要處理
> #!/bin/sh
>
> echo "Enter a keystroke"
> oldstty=`stty -g`
> stty -icanon -echo min 1 time 0
> key=`dd bs=4 count=1 <&0 2>/dev/null`
> stty $oldstty
> echo "key is" $key
小州兄這段程式則避開了這個問題
只是執行後所有KEYIN均不顯示了
只好綜合兩支程式
getc()
{
oldstty=`stty -g`
stty raw -echo min 1 time 0
eval $1=`dd bs=4 count=1 <&0 2>/dev/null`
stty $oldstty
stty cooked echo
}
echo "press a key"
getc ans
echo "this is you type:"
echo $ans
echo "bye!"
再研究如何取得功能鍵碼嚕 :P
-
getc()
{
oldstty=`stty -g`
stty raw -echo # min 1 time 0 只有-icanon 狀況下有用。
eval $1=`dd bs=4 count=1 <&0 2>/dev/null` # #<&0是要停止來自檔案的輸入嗎?bs=5因為f7的回應為5碼會造成錯誤
stty $oldstty
stty cooked echo } 試過可以刪除
echo "press a key"
getc ans
echo "this is you type:"
echo $ans
echo "bye!"
改成下面的樣子,連功能鍵都可以識別了
getc()
{
oldstty=`stty -g`
stty raw -echo
eval $1=`dd bs=5 count=1 2>/dev/null`
stty $oldstty
}
echo "press a key"
getc ans
echo "this is you type:"
echo $ans '+' ${ans#?}
echo "bye!"
但ctrl-系列仍然管不到
-
用這個方法應該比較正規
詳情請看 man bash 之 read
ans=""
echo -n "type key:<"
read -s -n 1 ans
echo $ans ">"
ans=""
read -s -n 1 ans
echo "<" $ans ">"
ans=""
read -n 5 -t 1 ans # 用這個可能還可以寫出動態的 shell
echo "<" $ans ">"
-
好訝異read有這些參數可用,看2nd Edition Linux in a nutshell原文舊書
(Feb 1999)真的查不到說…… 因為Linux的向下相容性,看天瓏打折
就買來看,反正是比自己列印man檔划算說。沒想到馬上就有查不到的東西。
更別說中文的指令辭典及Linux入門書介紹的內容。真的是找錯地方了! :(
-----------------------------------------------------------------------------
還是找男人比較有用 :lol:
jeffer兄,謝謝啦!真的獲益匪淺。用這方法 ` \ | 三個跳脫字符就不會引起程序錯誤。
仔細再看一遍:若用之前的寫法
eval $1='`dd bs=1 count=1 2>/dev/null`' #紅字部份不省略,\ ` |就不會造成錯誤跳出程序
比較傷腦筋的還是如何比對這些那些不易正常輸入的字符。c-A Esc Backspace...
-
各位學長
有沒有較方便使用的選單程式
就是只要改參數檔就可以更改選單內容的
我在網路上找到二個程式範例
有一個還有光棒移動的選單
但是寫的不夠完整沒有辦法直接執行
可否請各位學長幫忙測試看看
在Unix系統下用shell製作通用界面
http://www.ddvip.net/os/scounix/index1/4.htm
menu是shell寫成的shell函數
http://bbs.chinaunix.net/forum/24/20040414/304106.html
-
前面提的程式碼,摘錄如下:
getc()
{
oldstty=`stty -g`
stty raw -echo
eval $1=`dd bs=5 count=1 2>/dev/null`
stty $oldstty
}
echo "press a key"
getc ans
echo "this is you type:"
echo $ans '+' ${ans#?}
echo "bye!"
似乎無法抓到Enter鍵!
我正在撰寫光棒選單的基本架構,目前已經完成99%
目前遭遇的問題是無法抓到Enter鍵,希望有高手能夠指點迷津!
晚一點會將寫好的script貼上。
#!/bin/bash
ColorRED=1
ColorGREEN=2
ColorYELLOW=3
ColorBLUE=4
ColorMAGENTA=5
ColorCYAN=6
ColorGRAY=7
ColorWHITE=8
ColorEnhanceWHITE=9
ColorBLACK=10
#顯示彩色文字需要四個參數,分別是前景色、背景色、樣式及文字
function ColorText()
{
ForegroundColor="3""$1"
BackgroundColor="4""$2"
SetColor="\E[""$ForegroundColor;$BackgroundColor""m"
SetStyle="\033[""$3""m"
TextContent="$4"
ResetAll="\033[0m"
echo -e -n "$SetColor""$SetStyle""$TextContent""$ResetAll"
}
function Cursor()
{
local cursor_status
cursor_status=$1
case $cursor_status in
off|OFF)
echo -e "\033[?25l"
;;
on|ON)
echo -e "\033[?25h"
;;
*)
return 1
;;
esac
}
function GotoXY()
{
local row
local col
row=$1
col=$2
echo -e -n "\033[$row;$col""H""\033[0m"
}
function GetKey()
{
oldstty=`stty -g`
stty raw -echo
eval $1=`dd bs=5 count=1 2>/dev/null`
stty $oldstty
}
TotalItems=$(cat MenuItemName | wc -l)
Row_Of_Menu=5
Col_Of_Menu=5
clear
Cursor OFF
for ((ItemIndex=1; ItemIndex <= $TotalItems; ItemIndex++))
do
ItemName[$ItemIndex]=$(sed -n "$ItemIndex""p" MenuItemName)
ItemRow=$(expr $Row_Of_Menu + $ItemIndex)
GotoXY $ItemRow $Col_Of_Menu
ColorText $ColorWHITE $ColorBLUE 1 "$ItemIndex) ${ItemName[$ItemIndex]} ($ItemIndex"
done
CurrentIndex=1
while [ 1 ]
do
GotoXY $(expr $Row_Of_Menu + $TotalItems + 2) $Col_Of_Menu; echo "Key Char : " ${PressKey#?}
GotoXY $(expr $Row_Of_Menu + $TotalItems + 3) $Col_Of_Menu; echo "Current : " $CurrentIndex
Row_Of_BAR=$(expr $Row_Of_Menu + $CurrentIndex)
GotoXY $Row_Of_BAR $Col_Of_Menu
ColorText $ColorWHITE $ColorRED 1 "$CurrentIndex) ${ItemName[$CurrentIndex]} ($CurrentIndex"
GetKey PressKey
GotoXY $Row_Of_BAR $Col_Of_Menu
ColorText $ColorWHITE $ColorBLUE 1 "$CurrentIndex) ${ItemName[$CurrentIndex]} ($CurrentIndex"
if [ "${PressKey#?}" == "[B" ]; then
if [ $CurrentIndex == $TotalItems ]; then
CurrentIndex=1
else
((CurrentIndex++))
fi
fi
if [ "${PressKey#?}" == "[A" ]; then
if [ $CurrentIndex == 1 ]; then
CurrentIndex=$TotalItems
else
((CurrentIndex--))
fi
fi
if [ "$PressKey" == "0" ]; then
GotoXY $Row_Of_BAR $Col_Of_Menu
ColorText $ColorWHITE $ColorRED 1 "$CurrentIndex) ${ItemName[$CurrentIndex]} ($CurrentIndex"
GotoXY $(expr $Row_Of_Menu + $TotalItems + 4) $Col_Of_Menu
echo "Your selection is" ${ItemName[$CurrentIndex]}
Cursor ON
break
fi
done
MenuItemName的內容如下:
MenuItem #1
MenuItem #2
MenuItem #3
MenuItem #4
MenuItem #5
MenuItem #6
MenuItem #7
MenuItem #8
MenuItem #9