복합 명령 앞에 리디렉션 입력을 지정할 수 있나요?

복합 명령 앞에 리디렉션 입력을 지정할 수 있나요?

Bash를 사용하면 명령 앞에 리디렉션된 입력을 지정할 수 있습니다.

$ <lines sed 's/^/line: /g'
line: foo
line: bar

whileBash를 사용하면 루프 와 같은 복합 명령으로 입력을 리디렉션할 수도 있습니다 .

$ while read line; do echo "line: $line"; done <lines
line: foo
line: bar

그러나 루프 이전에 리디렉션 입력을 지정하려고 하면 while구문 오류가 발생합니다.

$ <lines while read line; do echo "line: $line"; done
bash: syntax error near unexpected token `do'

이게 무슨 문제야? Bash에서 복합 명령 앞에 리디렉션된 입력을 지정할 수 없습니까? 그렇다면 왜 안 됩니까?

답변1

man bash설명하다:

...리디렉션 연산자는 표현식 앞이나 뒤 어디든 나타날 수 있습니다.간단한 명령아니면 명령을 따를 수도 있습니다.

while단순한 명령이 아닙니다.

답변2

당신은 에 있을 수 있지만 에 있을 수 zsh는 없습니다 .bash초로바가 문서를 알려줬어요, 그러나 이전에 리디렉션하려면 다음을 수행할 수 있습니다.

< file eval '
  while IFS= read -r line; do
    ...
  done'

또는 (지원되는 시스템에서 /dev/fd/n):

< file 3<< 'EOF' . /dev/fd/3
while IFS= read -r line; do
  ...
done
EOF

(이것은 당신이하고 싶은 일이 아닙니다).

다음과 같이 할 수도 있습니다.

exec 3< file
while IFS= read -r line <&3; do
  ...
done
exec 3<&-

( exec스크립트를 열 수 없으면 스크립트가 종료됩니다.)file

또는 다음 기능을 사용하세요.

process()
  while IFS= read -r line; do
    ...
  done

< file process

답변3

입력하기 전에 해당 대체 항목을 사용하려면 다음 대체 항목을 사용할 수 있습니다.

cat lines | while read line; do echo "line: $line"; done

답변4

exec를 사용하여 표준 입력을 리디렉션할 수 있습니다.

스크립트에서:

exec < <(cat lines)
while read line ; do echo "line: $line"; done

그러나 로그인 셸에서는 사용할 수 없습니다(파일을 표준 출력으로 덤프하고 종료함). 이 경우 다른 파일 설명자를 열 수 있습니다.

exec 3< <(cat lines)
while read -u 3 line ; do echo "line: $line"; done

참고로:실행 사용

관련 정보