표준 입력이나 파일 이름이 모두 제공되면 폐기해야 합니까?

표준 입력이나 파일 이름이 모두 제공되면 폐기해야 합니까?

grepsed파일 이름 인수를 제공하면 stdin이 무시됩니다.

$ echo foo > test.txt
$ echo foobar | grep f test.txt 
foo
$ echo foobar | sed -e 's/foo/bar/' test.txt 
bar

이것이 확립된 모범 사례입니까? 그렇다면 왜 그렇습니까?

답변1

프로그램은 파일이 명령줄에 지정되어 있는지 알고 있습니다. stdin에서 사용 가능한 입력이 있는지(읽으려고 시도하는 것 외에) 알 수 있는 방법이 없으며, 입력이 있는 경우 프로그램은 해당 입력이 의도된 것인지 알 수 있는 방법이 없습니다. 따라서 유일하게 합리적인 옵션은 프로그램 호출 방식(명령줄 인수, 환경 변수, 구성 파일 등)에 따라 stdin에서 읽을지 여부를 결정하기 위한 명시적인 규칙을 갖는 것입니다.

예를 들어 일반적인 텍스트 유틸리티( cat, sort, grep, awk, perl -p, ...)는 파일이 제공되지 않으면 stdin에서 읽거나 파일이 제공되면 지정된 파일에서 읽습니다. 인터프리터는 유사한 규칙을 따릅니다. 예를 들어 지정된 파일에서 명령을 읽는 sh동안 인수 없이 표준 입력에서 명령을 읽습니다 sh script_file_name(또는 필요한 경우 스크립트가 stdin을 읽도록 합니다). -입력 파일 이름이 예상되는 위치에서 발생하는 경우 프로그램이 stdin에서 읽는 일반적인 규칙도 있습니다 .

다음과 같은 쉘 조각을 고려하십시오.

somecommand | while read line; do
  process "$line"
done

process표준 입력에서 읽을 지 여부를 알아야 합니다 . "stdin이 제공되는지 테스트"하는 것과 같은 것은 없습니다. stdin이 제공되지만 호출 프로그램 사용자는 stdin을 읽고 싶은지 여부를 알고 있습니다.

답변2

내가 찾은 대답은 그것이 설계된 방식이었습니다. 표준 입력 및 파일에서 데이터를 읽으려면 echo foobar | grep f - test.txt.from을 사용하십시오.man grep

 grep  searches the named input FILEs (or standard input if no files are
 named, or if a single hyphen-minus (-) is given as file name) for lines
 containing  a  match to the given PATTERN.  By default, grep prints the
 matching lines.

관련 정보