쉘 스크립트에서 입력을 일시 중지하고 사용자에게 선택을 요구합니다.
표준 Yes
, No
또는 Cancel
유형 질문입니다.
일반적인 bash 프롬프트에서 어떻게 이것을 수행합니까?
답변
쉘 프롬프트에서 사용자 입력을 얻는 가장 단순하고 가장 널리 사용되는 방법은 read
명령입니다. 사용법을 설명하는 가장 좋은 방법은 간단한 데모입니다.
while true; do
read -p "Do you wish to install this program?" yn
case $yn in
[Yy]* ) make install; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
또 다른 방법으로, 지적 으로 스티븐 Huwig은 , 배쉬의입니다 select
명령. 다음은 동일한 예입니다 select
.
echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
case $yn in
Yes ) make install; break;;
No ) exit;;
esac
done
으로 select
당신이 입력을 소독 할 필요가 없습니다 – 그것은 가능한 선택 사항을 표시합니다, 당신은 당신의 선택에 해당하는 번호를 입력합니다. 또한 자동으로 루프되므로 while true
잘못된 입력을 제공하는 경우 루프를 다시 시도 할 필요가 없습니다 .
또한, 레아 그리가 의 요청 언어 무신론자 만드는 방법 보여 그녀의 대답을 . 여러 언어를 더 잘 제공하기 위해 첫 번째 예를 적용하면 다음과 같습니다.
set -- $(locale LC_MESSAGES)
yesptrn="$1"; noptrn="$2"; yesword="$3"; noword="$4"
while true; do
read -p "Install (${yesword} / ${noword})? " yn
case $yn in
${yesptrn##^} ) make install; break;;
${noptrn##^} ) exit;;
* ) echo "Answer ${yesword} / ${noword}.";;
esac
done
분명히 다른 통신 문자열은 여기에서 번역되지 않은 채로 남아 있습니다 (설치, 답변). 더 완전한 완성 된 번역으로 해결해야하지만 부분 번역조차도 많은 경우에 도움이 될 것입니다.
마지막으로 F. Hauri 의 훌륭한 답변 을 확인하십시오 .
답변
하나의 일반적인 질문에 대해 최소 5 개의 답변.
에 따라
그리고 원한다면
- 간단한“인라인 ”질문 / 응답 (일반 솔루션)
- 꽤 형식화 된 인터페이스 ncurses libgtk 또는 libqt를 사용하는 그래픽
- 강력한 리드 라인 히스토리 기능 사용
1. POSIX 일반 솔루션
read
다음 명령을 사용할 수 있습니다 if ... then ... else
.
echo -n "Is this a good question (y/n)? "
read answer
# if echo "$answer" | grep -iq "^y" ;then
if [ "$answer" != "${answer#[Yy]}" ] ;then
echo Yes
else
echo No
fi
( Adam Katz의 의견에 감사드립니다 : 위의 테스트를 더 휴대하기 쉽고 포크 하나를 피하는 테스트로 대체했습니다.)
POSIX이지만 단일 키 기능
그러나 사용자가을 누르지 않게하려면 다음 Return과 같이 쓸 수 있습니다.
( 편집 : @JonathanLeffler가 올바르게 제안했듯이 stty의 구성을 저장 하는 것이 단순히 제자리 를 잡는 것보다 낫습니다 .)
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo ; answer=$(head -c 1) ; stty $old_stty_cfg # Careful playing with stty
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
fi
참고 : 이것은 아래에서 테스트되었습니다쉬, 세게 때리다, ksh, 대시 과 비지 박스!
동일하지만 명시 적으로 y또는 n:
#/bin/sh
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo
answer=$( while ! head -c 1 | grep -i '[ny]' ;do true ;done )
stty $old_stty_cfg
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
fi
전용 도구 사용
사용하여 구축 된 다양한 도구가 있습니다 libncurses
, libgtk
, libqt
또는 다른 그래픽 라이브러리. 예를 들어, 사용 whiptail
:
if whiptail --yesno "Is this a good question" 20 60 ;then
echo Yes
else
echo No
fi
시스템에 따라 whiptail
다른 유사한 도구 로 교체해야 할 수도 있습니다 .
dialog --yesno "Is this a good question" 20 60 && echo Yes
gdialog --yesno "Is this a good question" 20 60 && echo Yes
kdialog --yesno "Is this a good question" 20 60 && echo Yes
여기서 20
대화 상자의 높이는 줄 수이며 60
대화 상자의 너비입니다. 이 도구들은 모두 거의 같은 구문을 가지고 있습니다 .
DIALOG=whiptail
if [ -x /usr/bin/gdialog ] ;then DIALOG=gdialog ; fi
if [ -x /usr/bin/xdialog ] ;then DIALOG=xdialog ; fi
...
$DIALOG --yesno ...
2. 배쉬 특정 솔루션
기본 인라인 방법
read -p "Is this a good question (y/n)? " answer
case ${answer:0:1} in
y|Y )
echo Yes
;;
* )
echo No
;;
esac
필요한 경우 case
테스트 할 수 있도록 사용하는 것을 선호 yes | ja | si | oui
합니다 …
라인 에 하나의 키 기능
bash에서 read
명령 에 대한 의도 된 입력 길이를 지정할 수 있습니다 .
read -n 1 -p "Is this a good question (y/n)? " answer
bash에서 read
command는 시간 초과 매개 변수를 승인하는데 이는 유용 할 수 있습니다.
read -t 3 -n 1 -p "Is this a good question (y/n)? " answer
[ -z "$answer" ] && answer="Yes" # if 'yes' have to be default choice
3. 전용 도구에 대한 몇 가지 요령
간단한 yes - no
목적 이외의보다 정교한 대화 상자 :
dialog --menu "Is this a good question" 20 60 12 y Yes n No m Maybe
진행 표시 줄:
dialog --gauge "Filling the tank" 20 60 0 < <(
for i in {1..100};do
printf "XXX\n%d\n%(%a %b %T)T progress: %d\nXXX\n" $i -1 $i
sleep .033
done
)
작은 데모 :
#!/bin/sh
while true ;do
[ -x "$(which ${DIALOG%% *})" ] || DIALOG=dialog
DIALOG=$($DIALOG --menu "Which tool for next run?" 20 60 12 2>&1 \
whiptail "dialog boxes from shell scripts" >/dev/tty \
dialog "dialog boxes from shell with ncurses" \
gdialog "dialog boxes from shell with Gtk" \
kdialog "dialog boxes from shell with Kde" ) || exit
clear;echo "Choosed: $DIALOG."
for i in `seq 1 100`;do
date +"`printf "XXX\n%d\n%%a %%b %%T progress: %d\nXXX\n" $i $i`"
sleep .0125
done | $DIALOG --gauge "Filling the tank" 20 60 0
$DIALOG --infobox "This is a simple info box\n\nNo action required" 20 60
sleep 3
if $DIALOG --yesno "Do you like this demo?" 20 60 ;then
AnsYesNo=Yes; else AnsYesNo=No; fi
AnsInput=$($DIALOG --inputbox "A text:" 20 60 "Text here..." 2>&1 >/dev/tty)
AnsPass=$($DIALOG --passwordbox "A secret:" 20 60 "First..." 2>&1 >/dev/tty)
$DIALOG --textbox /etc/motd 20 60
AnsCkLst=$($DIALOG --checklist "Check some..." 20 60 12 \
Correct "This demo is useful" off \
Fun "This demo is nice" off \
Strong "This demo is complex" on 2>&1 >/dev/tty)
AnsRadio=$($DIALOG --radiolist "I will:" 20 60 12 \
" -1" "Downgrade this answer" off \
" 0" "Not do anything" on \
" +1" "Upgrade this anser" off 2>&1 >/dev/tty)
out="Your answers:\nLike: $AnsYesNo\nInput: $AnsInput\nSecret: $AnsPass"
$DIALOG --msgbox "$out\nAttribs: $AnsCkLst\nNote: $AnsRadio" 20 60
done
더 많은 샘플? USB 장치 및 USB 이동식 저장소 선택기 선택을 위해 whiptail 사용을 살펴보십시오 : USBKeyChooser
5. readline 기록 사용
예:
#!/bin/bash
set -i
HISTFILE=~/.myscript.history
history -c
history -r
myread() {
read -e -p '> ' $1
history -s ${!1}
}
trap 'history -a;exit' 0 1 2 3 6
while myread line;do
case ${line%% *} in
exit ) break ;;
* ) echo "Doing something with '$line'" ;;
esac
done
이것은 파일이 만들어집니다 .myscript.history
당신에 $HOME
당신이 같이 작성한 Readline의 역사 명령을 사용할 수있는 것보다, 디렉토리 Up, Down, Ctrl+ r등이 있습니다.
답변
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"
답변
내장 된 읽기 명령을 사용할 수 있습니다 . 이 -p
옵션을 사용하여 사용자에게 질문을하십시오.
BASH4부터는 이제 -i
답변을 제안하는 데 사용할 수 있습니다 .
read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
echo $FILEPATH
(단 -e
, 화살표 키로 줄을 편집 하려면 “readline”옵션을 사용해야합니다 )
“예 / 아니오”논리를 원하면 다음과 같이 할 수 있습니다.
read -e -p "
List the content of your home dir ? [Y/n] " YN
[[ $YN == "y" || $YN == "Y" || $YN == "" ]] && ls -la ~/
답변
Bash는 이 목적으로 선택 했습니다.
select result in Yes No Cancel
do
echo $result
done
답변
read -p "Are you alright? (y/n) " RESP
if [ "$RESP" = "y" ]; then
echo "Glad to hear it"
else
echo "You need more bash programming"
fi
답변
다음은 제가 함께 정리 한 것입니다.
#!/bin/sh
promptyn () {
while true; do
read -p "$1 " yn
case $yn in
[Yy]* ) return 0;;
[Nn]* ) return 1;;
* ) echo "Please answer yes or no.";;
esac
done
}
if promptyn "is the sky blue?"; then
echo "yes"
else
echo "no"
fi
나는 초보자이므로 소금 한알로 이것을 가져 가면 효과가있는 것 같습니다.
