stdin에서 인수를 읽는 셸 스크립트에서 "read" 명령을 사용하는 방법

stdin에서 인수를 읽는 셸 스크립트에서 "read" 명령을 사용하는 방법

우선, 미리 도움을 주셔서 감사드리며, 이전에 답변을 드려서 죄송합니다. 나는 그것을 찾을 수 없었다.

내 질문을 이해하는 데 도움을 주기 위해 "list_server_owners"라는 다음과 같은 간단한 스크립트를 작성했습니다(쓸모는 없지만 단지 예일 뿐입니다).

#!/bin/bash

SERVER_LIST=""
SERVER_LIST="$(cat) " # This reads from stdin

for SERVER in $SERVER_LIST
    do
    echo -n "Please, write the server's owner: "
    read OWNER
    echo "${SERVER}'s owner is $OWNER"
    done

"server_list"라는 다음 텍스트 파일이 있습니다.

Server1
Server2

그리고 이것은 stdin을 통해 "server_list"를 전달하는 스크립트의 출력입니다.

$ cat server_list | list_server_owner
Please, write the server's owner: Server1's owner is
Please, write the server's owner: Server2's owner is

문제는 설명하기 쉽습니다. "read OWNER" 스크립트 줄이 원하는 대로 작동하지 않습니다. 서버 소유자의 이름이 화면에 요청되지 않습니다.

화면에서 문자열을 "읽기" 요청하는 명령을 어떻게 만들 수 있는지 아시나요?

답변1

/dev/tty 파일은 프로세스의 제어 터미널과 동의어이므로 해당 장치의 입력을 리디렉션하면 됩니다.

...
read OWNER </dev/tty
...

/dev/tty 이전에 에코 프롬프트의 출력을 리디렉션한 다음 파이프에서 스크립트를 사용할 수도 있습니다.

#!/bin/bash

while read SERVER  # this reads from stdin
do
  echo -n "Please, write the server's owner: " >/dev/tty
  read OWNER </dev/tty
  echo "$SERVER:$OWNER"    # write to stdout
done

그리고 다음과 같이 사용하세요:

 cat server_list | assign_owner > server_owner

답변2

나는 해결책을 찾았습니다.

다음을 추가해야 합니다.

MY_TTY=$(ps -ef | grep -m 1 $$ | awk '{print $6}')
read OWNER </dev/${MY_TTY}

답변3

또 다른 가능성은 나에게 가장 간단합니다.

exec 0</dev/tty
read OWNER

이를 사용하면 스크립트의 모든 "읽기" 명령에 표준 입력을 지정할 필요가 없습니다.

스크립트 내부에 "tty" 명령을 작성하면 출력이 없기 때문에 혼란스러웠습니다. 그러나 마지막 설명에서 알 수 있듯이(감사합니다) 특수 파일 /dev/tty가 인식됩니다.

관련 정보