Bash에서 명령 또는 별칭에 "Are you sure [Y / n]"을 추가하는 방법은 무엇입니까?


228

이 특별한 경우에는 Bash에 확인을 추가하고 싶습니다.

확실합니까? [Y / n]

Mercurial의 hg push ssh://username@www.example.com//somepath/morepath경우 실제로 별명입니다. 별명에 추가 할 수있는 표준 명령이 있습니까?

그 이유는 것입니다 hg pushhg out비슷한 소리를 할 수 있고 내가 원하는 때 때때로 hgoutrepo, 나는 accidentlly 입력 할 수 있습니다 hgpushrepo(모두 별칭).

업데이트 : 이 같은이 될 수있는 경우 내장과 같은 다른 명령과 명령 : confirm && hg push ssh://...A에 대한 요청하실 수 있습니다 좋은 ... 단지 명령 것 그 yes또는 no그리고 만약 나머지를 계속합니다 yes.


1
별명 대신 함수 를 사용하려고 할 것입니다 . From info bash: "거의 모든 목적을 위해, 별칭보다 쉘 기능이 선호됩니다."
추후 공지가있을 때까지 일시 중지되었습니다.

정말? ls -l또는 같은 사람이라도 rm -i?
nonopolarity

5
에 대한 거의 모든 아니라 모든 . 그건 그렇고, 같은 것을 하지 마십시오 alias rm='rm -i'. 언젠가는 가장 필요할 때 별칭이 존재하지 않으며 boom!중요한 것이 손실됩니다.
추후 공지가있을 때까지 일시 중지되었습니다.

에 대한 별칭이 없으면 rm -i쉘 스크립트도 사용할 수 없습니다. 항상 매번 타이핑 rm -i합니까?
nonopolarity

8
습관 에 관한 것 입니다. 이전 주석에서 별명과 ​​같은 별명을 작성하고 입력 rm하고 -i행동을 예상 하는 습관을 들이게 될 수 있습니다. 그다음에 별명이 없습니다 (어떤 이유로 인해 설정되지 않았거나 설정되지 않았거나 다른 시스템에 있음) )를 입력하면 rm확인없이 즉시 항목을 삭제합니다. 죄송합니다! 그러나 같은 별칭 alias askrm='rm -i'을 사용하면 "명령을 찾을 수 없습니다"라는 오류가 표시되므로 괜찮을 것입니다.
추후 공지가있을 때까지 일시 중지되었습니다.

답변:


332

이것들은 Hamish의 대답 보다 더 작고 다재다능한 형태입니다 . 대문자와 소문자를 혼합하여 처리합니다.

read -r -p "Are you sure? [y/N] " response
case "$response" in
    [yY][eE][sS]|[yY]) 
        do_something
        ;;
    *)
        do_something_else
        ;;
esac

또는 Bash> = 버전 3.2의 경우 :

read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]
then
    do_something
else
    do_something_else
fi

참고 : $response빈 문자열 인 경우 오류가 발생합니다. 수정하려면 간단히 인용 부호를 추가하십시오 "$response". – 문자열을 포함하는 변수에는 항상 큰 따옴표를 사용하십시오 (예 : "$@"대신 $@).

또는 Bash 4.x :

read -r -p "Are you sure? [y/N] " response
response=${response,,}    # tolower
if [[ "$response" =~ ^(yes|y)$ ]]
...

편집하다:

편집에 대한 응답으로 다음 confirm은 내 대답의 첫 번째 버전을 기반으로 명령을 작성하고 사용하는 방법입니다 (다른 두 버전과 비슷하게 작동 함).

confirm() {
    # call with a prompt string or use a default
    read -r -p "${1:-Are you sure? [y/N]} " response
    case "$response" in
        [yY][eE][sS]|[yY]) 
            true
            ;;
        *)
            false
            ;;
    esac
}

이 기능을 사용하려면

confirm && hg push ssh://..

또는

confirm "Would you really like to do a push?" && hg push ssh://..

9
현재 테스트의 경우 [Y / N]이 아니라 [y / N]이어야합니다.
Simon A. Eugster 오전

not equal to두 번째 예 를 확인 하려면 $response변수를 캐스트해야한다는 점을 언급 할 가치가 있습니다 . 예 : if [[ ! $response =~ ^([yY][eE][sS]|[yY])$ ]].
João Cunha

@ JoãoCunha : =~정규식 일치 연산자 이므로 "같지 않음"보다는 "일치하지 않음" 입니다.
추후 공지가있을 때까지 일시 중지되었습니다.

@DennisWilliamson 맞습니다, 그것이 제가 의미하려고했던 것입니다. 어떤 이유로 내 댓글을 편집 할 수 없습니다.
João Cunha

6
좋은 범용 예 / 기능 없음 . 프롬프트를 강력하게 지원하고 선택적으로 'y'또는 'n'을 기본값으로 설정합니다.
wkw

19

여기 대략 원하는 스 니펫이 있습니다. 인수를 전달하는 방법을 알아 보겠습니다.

read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]
then
  # http://stackoverflow.com/questions/1537673/how-do-i-forward-parameters-to-other-command-in-bash-script
else
  exit 0
fi

yes | command name here:) 조심


13

캐리지 리턴으로 확인을 쉽게 우회 할 수 있으며 유효한 입력을 지속적으로 요구하는 것이 유용합니다.

이 작업을 쉽게 수행 할 수있는 기능이 있습니다. Y | N이 수신되지 않으면 "잘못된 입력"이 빨간색으로 나타나고 사용자에게 다시 프롬프트가 표시됩니다.

prompt_confirm() {
  while true; do
    read -r -n 1 -p "${1:-Continue?} [y/n]: " REPLY
    case $REPLY in
      [yY]) echo ; return 0 ;;
      [nN]) echo ; return 1 ;;
      *) printf " \033[31m %s \n\033[0m" "invalid input"
    esac 
  done  
}

# example usage
prompt_confirm "Overwrite File?" || exit 0

인수를 전달하여 기본 프롬프트를 변경할 수 있습니다


12

이러한 'yes'변형을 명시 적으로 확인하지 않으려면 bash 정규 표현식 연산자 '= ~'를 정규 표현식과 함께 사용할 수 있습니다.

read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt =~ [yY](es)* ]]
then
(etc...)

사용자 입력이 'y'또는 'Y'로 시작하고 그 뒤에 0 이상의 'es'가 있는지 테스트합니다.


5

이것은 해킹 일 수 있습니다.

문제 Unix / Bash에서 "xargs -p"는 명령을 실행하기 전에 확인을 요청하는 좋은 방법입니까?

우리는 일을 xargs하기 위해 사용할 수 있습니다 :

echo ssh://username@www.example.com//somepath/morepath | xargs -p hg push

물론 이것은 다음과 같은 별칭으로 설정됩니다 hgpushrepo

예:

$ echo foo | xargs -p ls -l
ls -l foo?...y
-rw-r--r--  1 mikelee    staff  0 Nov 23 10:38 foo

$ echo foo | xargs -p ls -l
ls -l foo?...n

$

4

/ etc / bashrc 파일에 다음을 추가하십시오. 이 스크립트는 "confirm"이라는 별명 대신 상주 "function"을 추가합니다.


function confirm( )
{
#alert the user what they are about to do.
echo "About to $@....";
#confirm with the user
read -r -p "Are you sure? [Y/n]" response
case "$response" in
    [yY][eE][sS]|[yY]) 
              #if yes, then execute the passed parameters
               "$@"
               ;;
    *)
              #Otherwise exit...
              echo "ciao..."
              exit
              ;;
esac
}

좋은. 하지만 약간의 수정은 : 당신이 주변에 따옴표를 넣어해야 $response하고 $@misparses을 피하기 위해, 일부 중복 세미콜론이, 그리고 *조건은 종료하지 반환해야합니다.
Gordon Davisson

분명히 말하면, 그것은 불필요한 진술의 끝에 단일 세미콜론입니다.
추후 공지가있을 때까지 일시 중지되었습니다.

4

이것은 너무 짧을 수도 있지만 내 개인적인 용도로는 훌륭하게 작동합니다.

read -n 1 -p "Push master upstream? [Y/n] " reply; 
if [ "$reply" != "" ]; then echo; fi
if [ "$reply" = "${reply#[Nn]}" ]; then
    git push upstream master
fi

read -n 1단지 하나 개의 문자를 읽습니다. 엔터를 칠 필요가 없습니다. 'n'또는 'N'이 아닌 경우 'Y'로 가정합니다. Enter를 누르면 Y도 의미합니다.

(실제 질문 : bash 스크립트를 만들고 이전에 지적했던 것이 아니라 해당 스크립트를 가리 키도록 별칭을 변경하십시오)


짧고 달콤한, 내가 필요한 것. 감사!
Raymo111 's

3
read -r -p "Are you sure? [Y/n]" response
  response=${response,,} # tolower
  if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
      your-action-here
  fi

따라서 공백 문자는 예를 의미합니까?
Xen2050

'yes 또는 y'를 제외한 모든 작업이 확인되므로 귀하가 옳습니다! @ xen2050
SergioAraujo

3

누르는 입력이 필요하지 않습니다

길지만 재사용 가능한 모듈 식 접근 방식은 다음과 같습니다.

  • 0= yes와 1= no를 반환
  • 누르기 엔터 필요 없음-단일 문자 만
  • 를 눌러 enter기본 선택을 수락 할 수 있습니다
  • 선택을 강제하기 위해 기본 선택을 비활성화 할 수 있습니다
  • zsh와 모두 에 적용 bash됩니다.

Enter 키를 누를 때 기본값은 "no"입니다

(가) 있습니다 Ncapitalsed된다. 여기에서 enter를 누르면 기본값이 적용됩니다.

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?

또한 [y/N]?자동으로 추가되었습니다. 기본 "no"가 허용되므로 아무 것도 에코되지 않습니다.

유효한 응답이 제공 될 때까지 다시 프롬프트하십시오.

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *

Enter 키를 누를 때 기본값은 "yes"입니다

(가) 있습니다 Y대문자입니다 :

$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *

위의 Enter 키를 누르면 명령이 실행되었습니다.

기본값 없음 enter-필요 y또는n

$ get_yes_keypress "Here you cannot press enter. Do you like this"
Here you cannot press enter. Do you like this [y/n]? k
Here you cannot press enter. Do you like this [y/n]?
Here you cannot press enter. Do you like this [y/n]? n
$ echo $?
1

여기에서, 1또는 거짓이 반환되었습니다. 에 대문자 사용 안함[y/n]?

암호

# Read a single char from /dev/tty, prompting with "$*"
# Note: pressing enter will return a null string. Perhaps a version terminated with X and then remove it in caller?
# See https://unix.stackexchange.com/a/367880/143394 for dealing with multi-byte, etc.
function get_keypress {
  local REPLY IFS=
  >/dev/tty printf '%s' "$*"
  [[ $ZSH_VERSION ]] && read -rk1  # Use -u0 to read from STDIN
  # See https://unix.stackexchange.com/q/383197/143394 regarding '\n' -> ''
  [[ $BASH_VERSION ]] && </dev/tty read -rn1
  printf '%s' "$REPLY"
}

# Get a y/n from the user, return yes=0, no=1 enter=$2
# Prompt using $1.
# If set, return $2 on pressing enter, useful for cancel or defualting
function get_yes_keypress {
  local prompt="${1:-Are you sure} [y/n]? "
  local enter_return=$2
  local REPLY
  # [[ ! $prompt ]] && prompt="[y/n]? "
  while REPLY=$(get_keypress "$prompt"); do
    [[ $REPLY ]] && printf '\n' # $REPLY blank if user presses enter
    case "$REPLY" in
      Y|y)  return 0;;
      N|n)  return 1;;
      '')   [[ $enter_return ]] && return "$enter_return"
    esac
  done
}
    
# Credit: http://unix.stackexchange.com/a/14444/143394
# Prompt to confirm, defaulting to NO on <enter>
# Usage: confirm "Dangerous. Are you sure?" && rm *
function confirm {
  local prompt="${*:-Are you sure} [y/N]? "
  get_yes_keypress "$prompt" 1
}    

# Prompt to confirm, defaulting to YES on <enter>
function confirm_yes {
  local prompt="${*:-Are you sure} [Y/n]? "
  get_yes_keypress "$prompt" 0
}

2

글쎄, 여기 내 버전이 confirmJames의 수정 버전입니다 .

function confirm() {
  local response msg="${1:-Are you sure} (y/[n])? "; shift
  read -r $* -p "$msg" response || echo
  case "$response" in
  [yY][eE][sS]|[yY]) return 0 ;;
  *) return 1 ;;
  esac
}

이러한 변경 사항은 다음과 같습니다.

  1. local변수 이름이 충돌하는 것을 방지하기 위해 사용
  2. read사용 $2 $3 ...당신이 사용할 수 있도록, 그 행동을 제어 -n하고-t
  3. read실패 하면 echo뷰티 라인을 피드
  4. Git on Windows유일한 없습니다 bash-3.1않고 있습니다 true또는 false그렇게 사용 return하는 대신. 물론 이것은 bash-4.4 (현재 Git for Windows) 와도 호환됩니다.
  5. "y"가 기본값임을 명확하게 나타내려면 IPython 스타일 "(y / [n])"을 사용하십시오.

2

이 버전은 하나 이상의 사건을 가질 수 있도록 y하거나 Y, n또는N

  1. 선택 사항 : 승인 질문이 제공 될 때까지 질문을 반복하십시오.

  2. 선택적으로 : 다른 답변은 무시

  3. 선택적으로 : 원하는 경우 터미널을 종료하십시오.

    confirm() {
        echo -n "Continue? y or n? "
        read REPLY
        case $REPLY in
        [Yy]) echo 'yup y' ;; # you can change what you do here for instance
        [Nn]) break ;;        # exit case statement gracefully
        # Here are a few optional options to choose between
        # Any other answer:
    
        # 1. Repeat the question
        *) confirm ;;
    
        # 2. ignore
        # *) ;;
    
        # 3. Exit terminal
        # *) exit ;;
    
        esac
        # REPLY=''
    }

이것도 주목하십시오 :이 함수의 마지막 줄에서 REPLY 변수를 지우십시오. 그렇지 않으면 echo $REPLY터미널을 열거 나 닫거나 다시 설정할 때까지 계속 설정되어 있습니다.


1

게임에 늦었지만 confirm이전 답변의 다른 기능을 만들었습니다 .

confirm ()
{
    read -r -p "$(echo $@) ? [y/N] " YESNO

    if [ "$YESNO" != "y" ]; then
        echo >&2 "Aborting"
        exit 1
    fi

    CMD="$1"
    shift

    while [ -n "$1" ]; do
        echo -en "$1\0"
        shift
    done | xargs -0 "$CMD" || exit $?
}

그것을 사용하려면 :

confirm your_command

풍모:

  • 프롬프트의 일부로 명령을 인쇄합니다
  • NULL 구분자를 사용하여 인수를 전달합니다.
  • 명령의 종료 상태를 유지

버그 :

  • echo -en작동 bash하지만 쉘에서 실패 할 수 있습니다
  • 인수가 echo또는xargs
  • 쉘 스크립팅이 어렵 기 때문에 다른 버그

1

시험,

 #!/bin/bash
 pause ()
 {
 REPLY=Y
 while [ "$REPLY" == "Y" ] || [ "$REPLY" != "y" ]
 do
  echo -e "\t\tPress 'y' to continue\t\t\tPress 'n' to quit"
  read -n1 -s
      case "$REPLY" in
      "n")  exit                      ;;
      "N")  echo "case sensitive!!"   ;; 
      "y")  clear                     ;;
      "Y")  echo "case sensitive!!"   ;;
      * )  echo "$REPLY is Invalid Option"     ;;
 esac
 done
 }
 pause
 echo "Hi"

0

이것은 정확히하지 않은 그러나 다만 해킹 "예, 아니오 요구"별명은 hg push ...하지 않는 hgpushrepo것이 아니라 hgpushrepoconfirmedpush내가 모든 일을 철자 수와 시간, 왼쪽 뇌는 논리적 인 선택을했다.


1
그러나 당신은 당신이 TAB열쇠 를 사용할 것이라는 것을 알고 있습니다 !
Hamish Grubijan

그래, 사실,하지만 적어도 나는 명령을 한눈에보고 이상하고 두 번 생각하기 전에 Enter를 누르십시오
nonopolarity

0

동일하지 않지만 어쨌든 작동하는 아이디어.

#!/bin/bash  
i='y'  
while [ ${i:0:1} != n ]  
do  
    # Command(s)  
    read -p " Again? Y/n " i  
    [[ ${#i} -eq 0 ]] && i='y'  
done  

출력 :
다시? 예 /
아니요 다시? 예 /
아니요 다시? 예 /
아니요 7 다시? 예 /
아니요? 예 / 아니요 nsijf
$

이제 $ i read의 첫 번째 문자 만 검사합니다.


0

아래 코드는 두 가지를 결합한 것입니다

  1. 대소 문자를 구분하지 않는 shopt -s nocasematch

  2. 두 입력을 모두 받아 들일 조건이 있으면 yes, Yes, YES, y를 전달하십시오.

    shopt -s nocasematch

    [[sed-4.2.2. $ LINE = ~ (yes | y) $]] 인 경우

    그런 다음 0을 종료하십시오.

    fi


0

현지화 된 정규식을 사용하는 솔루션이 있습니다. 따라서 독일어에서 "Ja"에 대한 "j"는 예로 해석됩니다.

첫 번째 인수는 질문입니다. 두 번째 인수가 "y"이면 yes보다 기본 답변이되고, 그렇지 않으면 no가 기본 답변이됩니다. 응답이 "예"이면 리턴 값은 0이고 응답이 "아니오"이면 1입니다.

function shure(){
    if [ $# -gt 1 ] && [[ "$2" =~ ^[yY]*$ ]] ; then
        arg="[Y/n]"
        reg=$(locale noexpr)
        default=(0 1)
    else
        arg="[y/N]"
        reg=$(locale yesexpr)
        default=(1 0)
    fi
    read -p "$1 ${arg}? : " answer
    [[ "$answer" =~ $reg ]] && return ${default[1]} || return ${default[0]}
}

기본 사용법은 다음과 같습니다.

# basic example default is no
shure "question message" && echo "answer yes" || echo "answer no"
# print "question message [y/N]? : "

# basic example default set to yes
shure "question message" y && echo "answer yes" || echo "answer no"
# print "question message [Y/n]? : "
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.