bash: 파일을 읽을 때 사용자 입력 프롬프트

bash: 파일을 읽을 때 사용자 입력 프롬프트

탭으로 구분된 파일을 구문 분석하는 bash 스크립트를 작성 중입니다. 파일에 "prompt"라는 단어가 포함되어 있으면 스크립트는 사용자에게 값을 입력하도록 요청해야 합니다.

파일을 읽을 때 "읽기"를 단순히 건너뛰기 때문에 "읽기" 명령이 표준 입력에서 읽지 못하는 것 같습니다.

파일과 표준입력(stdin)에서 데이터를 읽는 솔루션을 갖고 있는 사람이 있나요?

참고: 이 스크립트는 Git Bash 및 MacOS에서 실행되어야 합니다.

다음은 실패한 작은 코드 예제입니다.

#!/bin/bash

#for debugging
set "-x"


while IFS=$'\r' read -r line || [[ -n "$line" ]]; do
  [[ -z $line ]] && continue

  IFS=$'\t' read -a fields <<<"$line"

  command=${fields[0]}

  echo "PROCESSING "$command
  if [[ "prompt" = $command ]]; then
    read -p 'Please enter a value: ' aValue
    echo
  else 
    echo "Doing something else for "$command
  fi
done < "$1"

산출:

$ ./promptTest.sh promptTest.tsv
+ IFS=$'\r'
+ read -r line
+ [[ -z something       else ]]
+ IFS=' '
+ read -a fields
+ command=something
+ echo 'PROCESSING something'
PROCESSING something
+ [[ prompt = something ]]
+ echo 'Doing something else for something'
Doing something else for something
+ IFS=$'\r'
+ read -r line
+ [[ -z prompt ]]
+ IFS=' '
+ read -a fields
+ command=prompt
+ echo 'PROCESSING prompt'
PROCESSING prompt
+ [[ prompt = prompt ]]
+ read -p 'Please enter a value: ' aValue
+ echo

+ IFS=$'\r'
+ read -r line
+ [[ -n '' ]]

TSV 파일 예:

$ cat promptTest.tsv
something       else
prompt
otherthing       nelse

답변1

가장 간단한 방법은 /dev/tty키보드 입력을 읽는 것으로 사용하는 것입니다.

예를 들어:

#!/bin/bash

echo hello | while read line
do
  echo We read the line: $line
  echo is this correct?
  read answer < /dev/tty
  echo You responded $answer
done

터미널에서 실행하지 않고 입력이 프로그램으로 리디렉션되는 것을 허용하지 않으면 프로그램이 중단되지만 그렇지 않으면 정상적으로 작동합니다.

보다 일반적으로는 원래 표준 입력을 기반으로 새 파일 핸들을 가져와서 읽을 수 있습니다. 라인 execread

#!/bin/bash

exec 3<&0

echo hello | while read line
do
  echo We read the line: $line
  echo is this correct?
  read answer <&3
  echo You responded $answer
done

두 경우 모두 프로그램은 다음과 같습니다.

% ./y
We read the line: hello
is this correct?
yes
You responded yes

두 번째 변형은 입력 리디렉션도 허용합니다.

% echo yes | ./y
We read the line: hello
is this correct?
You responded yes

답변2

이 SO Q&A의 제목은 다음과 같습니다.Bash에서 파일이나 표준 입력을 읽는 방법은 무엇입니까?찾고 있는 것과 유사한 작업을 수행하는 방법을 강조하는 이 방법을 보여줍니다.

while read line
do
  echo "$line"
done < "${1:-/dev/stdin}"

답변3

리디렉션하기 전에 표준 입력을 복사할 수 있습니다.

#!/bin/bash
# Assuming here fd 4 is unused.  Dup file descriptor 0 (stdin) to
# file descriptor 4
exec 4<&0 

while read x; do # Read from stdin (the file b/c of redirect below)
    echo "From $1: $x"
    read y <&4 # Read from file descriptor 4 (the original stdin)
    echo "From keyboard: $y"
done < "$1"

관련 정보