중복 가능성:
주문 리디렉션
현재 셸의 입력과 출력을 독립적으로 리디렉션하는 것 외에 exec >&2
다음 명령의 동작에 차이가 있습니까 ?
echo -en "C\nB\nA\n" | sort 2>/dev/stdout >&2
echo -en "C\nB\nA\n" 2>/dev/stdout >&2 | sort
2>/dev/stdout >&2 echo -en "C\nB\nA\n" | sort
위의 명령이 동일하다면 선호되는 변형은 무엇입니까?
답변1
먼저,간단한 명령(기본적으로 프로그램 이름 뒤에는 일부 매개변수가 옵니다.) 매개변수와 리디렉션의 상대적 위치는 중요하지 않습니다. 명령 이름 앞에 리디렉션할 수도 있습니다. 다음은 모두 동일합니다.
foo --bar qux >out 2>err
foo >out --bar 2>err
>out 2>err foo --bar qux
(모든 가능성을 나열하지는 않겠습니다.) 리디렉션을 마지막에 두는 것이 일반적이므로 그렇지 않으면 미래의 독자들이 놀랄 수도 있습니다. 그러나 이는 스타일의 문제일 뿐입니다. 명령 앞에 입력 리디렉션을 배치하고 명령 뒤에 출력 리디렉션을 배치하면 특히 파이프라인에서 읽기 순서가 처리 순서와 동일해지기 때문에 몇 가지 이점이 있습니다.
<input.txt command1 | command2 | command3 >output.txt
( command1 <input.txt | command2 …
첫 번째 처리 단계 후에 원점을 배치하는 것과 대조됩니다.)
복합 명령에서는 리디렉션을 마지막에 배치해야 합니다. 예를 들어 다음 코드 조각에서는 리디렉션을 다른 곳에 배치할 수 없습니다.
while some_predicate; do some_action; done <in >out
{ command1; command2; } <in >out
여러 리디렉션이 있는 경우 겹치는 경우, 즉 공통 파일 설명자가 있는 경우 순서가 중요합니다. 바라보다주문 리디렉션
파이프라인에서는 리디렉션이 모든 파이프라인 명령에 적용됩니다. 귀하의 예에서 리디렉션은 sort
(1) 명령과 (2,3) echo
명령에만 작동합니다. 위에서 언급했듯이 (2)와 (3)은 동일합니다.
(2)와 (3)에서 출력은 echo
리디렉션 전에 동일한 위치에서 끝납니다. 이라고 쓰면 echo -en "C\nB\nA\n" >&2 | sort
파이프 왼쪽에 있는 명령이 stdout에 아무 것도 출력하지 않으므로 sort
빈 stdin이 표시됩니다.
명령 블록을 중괄호로 묶어 명령 블록의 입력 또는 출력을 리디렉션할 수 있습니다.
{ command1 | command2; } 2>error.log
나는 당신이 선택한 리디렉션이 단지 데모 목적일 뿐이라고 가정합니다. 2>/dev/stdout >&2
작성하는 방법은 복잡합니다 2>&1
(표준 오류(예: fd 2)를 현재 표준 출력(예: fd 1)이 있는 위치로 리디렉션).
답변2
1은 2, 3과 다릅니다. 2와 3은 동일합니다.
버전 1에서는 C\nB\nA\n
으로 전송되는 FD 2가 원래 대상( ) 에서 로 매핑 sort
되고 , 그런 다음 어쨌든 도착했을 FD 1이 로 전송됩니다 ( 다소 무의미함).sort
STDERR
STDOUT
STDOUT
sort
STDOUT
버전 2와 3에서는 echo
FD 2가 STDERR
원래 목적지()에서 매핑된 STDOUT
후 어차피 도착했을 FD 1이 ' STDOUT
로 전송됩니다 .echo
STDOUT
기능적으로 이러한 명령 중 하나가 STDERR
.
버전 1에서는 echo
무언가를 FD 2로 출력하면 FD 2로 이동 STDERR
하지만 버전 2와 3에서는 으로 이동합니다 STDOUT
(따라서 파이프로도 연결됨 sort
). 또한 버전 1에서는 sort
FD 2로 무언가를 보내면 으로 이동하지만 STDOUT
버전 2와 3에서는 해당 출력이 로 이동합니다 STDERR
.
"선호되는 변형"에 관한 한, 실제로 다음과 같은 것을 더 사용해야 합니다(원한다고 echo
가정 STDERR
) sort
.
echo -en "C\nB\nA\n" 2>&1 | sort
이는 FD 1이 기본적으로 이미 포함되어 STDOUT
있고 FD 2가 파일 설명을 해당 설명자에 복사하도록 하기 때문에 작동합니다.