중첩 된 사례 명령문에서 스크립트를 건너 뛰는 사용자 입력 [yY] |

사용자 입력이 예상되는 중첩 된 사례 진술을 작성하려고합니다 (Y / N). 그러나 시스템은 입력을 기다리지 않으며 항상 “예 또는 아니오로 응답하십시오”라는 세 번째 옵션으로 이동합니다. 누구든지 내가 빠진 것을 말해 줄 수 있습니까?

사례 진술은 다음과 같습니다.

#!/bin/bash
STATUS=status

find /etc/init.d/* -name '*' -print0 | while IFS= read -r -d '' FILE;
do
if [ "$FILE" != "." -o "$FILE" != ".." ]; then
OUTPUT=$($FILE $STATUS)
case "$OUTPUT" in
    *disabled* )
        echo "Do you wish to start $FILE ?"
        read  yn
        case $yn in
         [yY] | [yY][Ee][Ss] )
                $FILE start
                ;;
         [nN] | [n|N][O|o] )
                ;;
        * )
        echo "Please answer yes or no.";;
        esac
        ;;
       * )
        echo "App $FILE is running"
;;
esac
fi
done

우분투 14.04 LTS에서 실행

샘플 출력

App /etc/init.d/reboot is running
App /etc/init.d/resolvconf is running
App /etc/init.d/rsync is running
App /etc/init.d/rsyslog is running
App /etc/init.d/samba is running
App /etc/init.d/samba-ad-dc is running
Do you wish to start /etc/init.d/saned ?
Please answer yes or no.


답변

findwhile 루프로 출력을 파이핑 하고 있습니다. 내부 읽기 명령은 findstdin이 아닌의 출력 에서 행을 읽습니다 .

다음과 같이 재구성 할 수 있습니다 find. 다른 파일 설명 자의 while 루프로 출력을 보냅니다 . 이것은 내부 읽기를 위해 stdin을 자유롭게 둡니다.

while IFS= read -u3 -r -d '' FILE; do
    if [ "$FILE" != "." -o "$FILE" != ".." ]; then
        OUTPUT=$($FILE $STATUS)
        case "$OUTPUT" in
            *disabled* )
                read -p "Do you wish to start $FILE ?" yn
                case $yn in
                    [yY] | [yY][Ee][Ss] ) $FILE start ;;
                    [nN] | [nN][Oo] ) ;;
                    * ) echo "Please answer yes or no.";;
                esac
                ;;
            * ) echo "App $FILE is running" ;;
        esac
    fi
done  3< <(find /etc/init.d/* -name '*' -print0)

파이프 대신 프로세스 대체를 사용하여find


답변

이번 상황은 답을 제공합니다. find의 출력을 전체 while 루프로 파이핑하고 여기에는 내부 읽기도 포함됩니다. 즉, “read yn”은 “find”가 제공하는 것과 동일한 출력에서 ​​읽습니다. 건반.

또한 파일을 반복하는 일반적인 처리를 싫어합니다. 간단한:

for file in /etc/init.d/*; do
   echo Processing $file
done

많은 양의 파일에 대해서도 오늘날에는 잘 작동합니다.

실제로 find를 사용해야한다면 핸들러를 다른 스크립트로 감싸서 다음과 같이 각 파일에 대해 호출 할 수 있습니다.

find /etc/init.d -type f -perm +111 -exec myhandlerscript.sh {} \;

실행 가능한 권한이있는 모든 파일을 찾고 이름이 인수 인 각 파일에 대해 myhandlerscript.sh를 호출합니다. 스크립트 내에서 파일 이름은 $ 1 특수 변수 안에 나타납니다.

실제로 같은 파일에 있어야하는 경우 함수 내에서 코드를 랩핑하고 “export -f myfunction”으로 내보내고 “-exec bash -c ‘myfunction”$ 0 “‘{} \;”을 사용하십시오. 찾을 매개 변수로


답변

“읽기”명령의 사용법이 옳지 않은 것 같습니다.

read -p "Do you wish to input data ?" yn

-p 스위치는 바로 옆에 문자열을 요구하며 프롬프트로 사용됩니다. 따라서 “yn”은 답변을 저장할 변수가 아니라 표시 할 내용이라고 생각했습니다.