나는 어떤 신인이 내 대답 중 하나를 위해 UUOC를 고정하려고 시도했을 때까지 그 상을 알지 못했습니다. 이었다 cat file.txt | grep foo | cut ... | cut ...
. 나는 그에게 내 마음의 한 조각을 주었다. 그렇게 한 후에야 그는 그 링크를 방문하여 그상의 기원과 그렇게하는 관행을 언급하게되었다. 더 많은 검색을 통해이 질문으로 이어졌습니다. 안타깝게도 의식적인 고려에도 불구하고 어떤 대답도 나의 근거를 포함하지 않았다.
나는 그를 교육 할 때 방어 적이 지 않았습니다. 결국, 어린 시절 grep foo file.txt | cut ... | cut ...
에 자주 단일 싱글을 수행 할 때마다 grep
파일 인수의 배치를 배우고 첫 번째가 패턴이고 후자가 파일 이름이라는 준비가되어 있기 때문에 명령을 작성했을 것입니다.
cat
"좋은 맛"(리누스 토발즈의 말로) 이유 때문에 주로 접두사로 질문에 대답했을 때 의식적인 선택이었습니다 .
후자의 이유가 더 중요하므로 먼저 설명하겠습니다. 파이프 라인을 솔루션으로 제공하면 재사용 할 수있을 것으로 기대합니다. 파이프 라인은 다른 파이프 라인의 끝에 추가되거나 다른 파이프 라인에 연결될 가능성이 높습니다. 이 경우 grep하는 파일 인수를 사용하면 재사용 성이 향상되고 파일 인수가 존재하는 경우 오류 메시지없이 자동으로 수행 할 수 있습니다. 나. grep foo xyz | grep bar xyz | wc
얼마나 많은 라인에서 당신을 줄 것 xyz
포함 bar
하면 모두 포함하는 행의 수를 예상하는 동안 foo
과 bar
. 파이프 라인에서 명령에 대한 인수를 사용하기 전에 명령을 변경해야하는 경우 오류가 발생하기 쉽습니다. 침묵 실패의 가능성을 추가하고 특히 교활한 연습이됩니다.
이전의 이유는 "좋은 맛"이 많기 때문에 교육을 필요로하는 사람이 "그렇지 않다"고 말하는 순간에 바로 생각할 수없는 위의 침묵 실패와 같은 것에 대한 직관적 인 잠재 의식적 이론적 근거이기 때문에 중요하지 않습니다. 그 고양이 쓸모없는 ".
그러나 나는 또한 내가 언급 한 이전의 "좋은 맛"이유를 의식적으로 만들려고 노력할 것이다. 그 이유는 Unix의 직교 디자인 정신과 관련이 있습니다. grep
하지 않습니다 cut
및 ls
하지 않습니다 grep
. 따라서 최소한 grep foo file1 file2 file3
디자인 정신에 위배됩니다. 그것을하는 직교 방법은입니다 cat file1 file2 file3 | grep foo
. 이제는 grep foo file1
의 특별한 경우 일 뿐이며 grep foo file1 file2 file3
, 동일하게 취급하지 않으면 적어도 쓸모없는 고양이 상을 피하려고하는 두뇌 시계 사이클을 사용하고 있습니다.
그것은 우리를 grep foo file1 file2 file3
연결 시키는 논쟁으로 이끈다 . 그리고 cat
그것이 합당 해 지도록 합당하게 연결되어 있기 때문에 연결되어 있지 cat file1 file2 file3
않기 때문에 우리는 전능하신 유닉스 의 정신을 위배한다 . 그렇다면, 유닉스는 한 파일의 출력을 읽고 stdout에 뱉어 내기 위해 다른 명령이 필요할 것입니다 (파일을 파기하거나 stdout에 대한 순수한 침을 뱉는 것이 아닙니다). 당신은 당신이 말하는 상황을했을 그래서 하거나 말을 하고 양심적으로 방지하기 위해 기억 도 피하면서, 상을 받고 피하기 위해 의 희망 디자인 때문에 여러 개의 파일을 지정하는 경우 오류가 발생합니다.cat
cat file1 | grep foo
cat
cat file1 file2
dog file1
cat file1
dog file1 file2
dog
이 시점에서 파일을 stdout에 뱉어내는 별도의 명령을 포함하지 cat
않고 다른 이름을 지정 하는 대신 연결을위한 이름 을 지정하는 데 대해 Unix 디자이너와 동정 하기를 바랍니다. <edit>
불행한 <
연산자 같은 개가 있습니다. 파이프 라인 끝 부분에 배치하면 안타깝게도 쉽게 작곡 할 수 있습니다. 처음에 구문 적으로 또는 미적으로 깨끗한 방법은 없습니다. 그것은 일반적으로 충분하지 않아 불행히도 개로 시작하지만 이전 파일 이후에 처리하려면 다른 파일 이름을 추가하십시오. ( >
반면에 절반은 나쁘지 않습니다. 끝 부분에 거의 완벽한 배치가 있습니다. 일반적으로 파이프 라인의 재사용 가능한 부분이 아니기 때문에 상징적으로 구별됩니다.)</edit>
다음 질문은 더 이상 처리하지 않고 단순히 파일을 뱉어 내거나 여러 파일을 stdout에 연결하는 명령을 갖는 것이 중요한 이유는 무엇입니까? 한 가지 이유는 표준 입력에서 작동하는 모든 단일 Unix 명령이 하나 이상의 명령 행 파일 인수를 구문 분석하고 존재하는 경우이를 입력으로 사용하는 방법을 알기위한 것입니다. 두 번째 이유는 사용자가 다음을 기억하지 않도록하기위한 것입니다 : (a) 파일 이름 인수가가는 곳; (b) 위에서 언급 한 바와 같이 무성 파이프 라인 버그를 피하십시오.
그것은 왜 우리에게 grep
여분의 논리가 있는지 알려줍니다 . 이론적 근거는 파이프 라인이 아닌 자주 사용되는 독립형 명령에 대한 사용자 유창성을 허용 하는 것입니다. 유용성이 크게 향상되기 위해 직교성이 약간 손상되었습니다. 모든 명령을 이런 식으로 설계해야하는 것은 아니며 자주 사용하지 않는 명령은 파일 인수의 추가 논리를 완전히 피해야합니다 (추가 논리는 불필요한 취약성을 초래합니다 (버그 가능성). 의 경우와 같은 파일 인수를 허용하는 것은 예외입니다 grep
. (참고 ls
로 파일 인수를 수락 할뿐만 아니라 거의 파일 인수를 요구하는 완전히 다른 이유가 있습니다.)
마지막으로, 표준 입력을 사용할 수있는 경우와 같은 예외적 인 명령 이 오류를 생성하는 경우 grep
( 더 나은 것은 아님 ls
) 더 잘 수행 할 수 있습니다. 명령에 사용자 편의를 위해 전능 한 Unix의 직교 정신을 위반하는 논리가 포함되어 있기 때문에 이는 합리적입니다. 추가적인 사용자 편의, 즉 자동 장애로 인한 고통을 방지하기 위해, 이러한 명령은 자동 장애의 가능성이있는 경우 사용자에게 경고하여 자신의 위반을 위반하는 것을 망설이지 않아야합니다.