Bash 명령줄의 read, echo 및 grep 명령 이해

Bash 명령줄의 read, echo 및 grep 명령 이해

Bash 라인에서 무슨 일이 일어나고 있는지 단계별로 설명할 수 있는 사람이 있나요? 저는 여기에 처음 왔으며 특히 다음에서 이 코드가 어떻게 작동하는지 이해하려고 노력하고 있습니다 echo.

read char; echo -e "YES\nNO\n" | grep -i $char

답변1

char이 줄의 명령은 사용자 대화형 방식으로 문자열을 변수로 읽어옵니다 .

echo+파이프는 grep입력 문자열이 양수 문자열인지 확인하려고 시도합니다. 대소문자를 구분하지 않고 입력 문자열(입력 문자열을 패턴으로 사용) YES과 단어 합계를 비교하여 이를 수행합니다 . NO사용자가 단어에 있는 대문자나 소문자 또는 하위 문자열을 입력하면 YES결과는 가 되며 YES, 문자열에 있는 대문자나 소문자나 하위 문자열을 입력하면 NO결과는 가 됩니다 NO. 이와 같은 내용을 입력하면 maybe빈 출력이 발생합니다.

이 접근 방식의 단점은 예를 들어 사용자가 와 를 입력하면 둘 다 일치한다는 것입니다. .왜냐하면 YESNOgrep모든 문자와 일치하는 정규식으로 처리되기 때문입니다. $char호출에 따옴표가 없으므로 사용자 grep/*/*/*/*/../../../../*/*/*/*입력과 같은 쉘 글로빙 패턴을 입력하는 경우(예는 다음에서 가져옴)bash/POSIX 쉘에서 변수를 인용하는 것을 잊어버리는 보안 위험). -r -o -e . /예를 들어 명령의 출력을 왜곡 할 수도 있습니다. 예를 들어 (이는 각각의 비이진 파일의 각 문자에 대해 해당 파일이 속한 파일의 경로 이름 앞에 별도의 줄을 출력합니다).

당신이 보여주는 코드는 본질적으로 사용자 입력을 사용한다는 점에서 "이상하고 특이"합니다.암호즉, 사용자 입력을 다음과 같이 사용합니다.무늬, 정적 테스트데이터이 가변 패턴의 경우. 이는 사용자의 입력을 받아 정적 스키마에 대해 이 변경 가능한 데이터를 테스트하는 일반적으로 수행되는 작업과 반대됩니다.

다음과 유사한 코드를 사용하는 것이 더 일반적입니다.

read -p 'Yes/[N]o: ' yesno
if [[ $yesno == [Yy]* ]]; then
   # code for affirmative
else
   # code for non-affirmative
fi

위 코드는 사용자로부터 문자열을 읽고 문자열이 y또는 Y문자로 시작하는지 테스트합니다. 그렇다면 명령문의 첫 번째 분기가 선택되고 if, 그렇지 않으면 기본적으로 선택됩니다 else.

분명히 전체 단어를 테스트 YES하거나 [Yy][Ee][Ss]대소문자를 구분하지 않고 일치를 테스트하거나 유효성 검사를 통해 입력 루프를 수정할 수도 있습니다.

while true; do
    read -p 'Yes/No: ' yesno

    if [ "$yesno" = Yes ] || [ "$yesno" = No ]; then
        break
    fi

    echo 'Please enter "Yes" or "No"' >&2
done

# $yesno is either Yes or No here

(또는 이와 유사한 것).

위의 두 예제 코드가 사용자 입력을 패턴이 아닌 데이터로만 사용하는 방법에 주목하세요.

원래 명령을 최소한 관용적인 것으로 다시 작성하면(그러나 기능이 다르고 완벽하지는 않을 수도 있음)

read yesno; printf '%s\n' "${yesno^^}" | grep -i -w -E 'yes|no'

사용자가 또는 를 입력하면 대문자 YES또는 가 반환됩니다. 이는 사용자가 단순한 등 이상의 내용을 입력해야 한다는 점에서 기능적으로 다릅니다.NOyesnoeyes

답변2

좋습니다. 각 명령을 차례로 실행해 보겠습니다.

read char

이는 표준 입력(일반적으로 키보드이지만 간접 파일이나 파이프 스트림일 수 있음, 아래 참조)에서 읽고 수신된 데이터를 이름이 지정된 변수에 배치합니다 char.

echo -e "YES\nNO\n"

echo제공된 인수는 표준 출력(일반적으로 터미널)으로 인쇄됩니다. 이 -e스위치(일반적으로 항상 그런 것은 아니며 echo일관된 구현에 몇 가지 문제가 있음) 를 사용하면 e일부 기본 형식화에 대해 특정 문자를 이스케이프할 수 있습니다. 이 경우 \n이스케이프된 을 사용하고 n있으며 ewline의 약자입니다 n.

grep -i $char

grep제공된 패턴과 일치하는 항목이 있는지 확인하기 위해 제공된 입력을 검색하는 도구입니다. 이 스위치는 대소문자를 구분하지 않고 검색 -i하도록 지시합니다 .i

그것 과 명령 |사이에 "파이프"가 있습니다 . 이는 첫 번째 명령의 출력을 두 번째 명령의 입력에 연결합니다. 즉, 말뭉치는 변수 내용에 반영된 패턴을 검색합니다.echogrepgrepchar

YES
NO

이 명령 시퀀스의 실제 결과는 제공된 입력(변수 이름을 기반으로 단일 문자로 간주되지만 확인되지 않음)을 보는 것입니다. 문자가 Y, E, S, y또는 e이면 s출력은 입니다 YES. 문자가 N, O, n또는 이면 o출력은 입니다 NO. 그러나 (예를 들어) 입력이 yo또는 인 경우 ne아무것도 출력되지 않습니다.

앞서 언급했듯이 입력이 문자라는 가정은 확인되지 않습니다. 이것은 주어진 예제 명령 시퀀스에서 유일한 안티 패턴이 아닙니다. 예를 들어 변수가 참조되지 않고 정규식 도구( grep)가 입력의 정규식 와일드카드 필터링 없이 사용되고 있습니다.

답변3

에서 "문자"(문자열 아님)를 읽습니다 /dev/stdin. 의미: 직접 입력하세요.

/dev/stdout그런 다음 콘솔을 의미 하는 두 줄이 출력됩니다 .

그런 다음 파이프("|")를 통해 대소문자를 구분하지 않는 입력 버전으로 이동합니다.

즉, "bar"를 입력하면 아무런 출력도 없이 단순히 완료되지만 "y"를 입력하면 "YES" 줄이 출력되고 "Y"도 강조 표시될 가능성이 높습니다.

관련 정보