본문 바로가기
리눅스

Redirection (computing)

by 다움위키 2023. 12. 9.

컴퓨팅에서, 리다이렉션(redirection)은 프로세스-사이 통신의 한 형식이고, 표준 스트림을 사용자-지정 위치로 리다이렉션할 수 있는 다양한 유닉스 쉘을 포함하여 대부분의 명령-줄 해석기에 공통적인 기능입니다.

유닉스-계열 운영 시스템에서, 프로그램은 dup2(2) 시스템 호출, 또는 덜 유연하지만 더 높은 수준의 stdio 아날로그, freopen(3)popen(3)와 함께 리다이렉션을 수행합니다.

Redirecting standard input and standard output

리다이렉션은 보통 명령 사이에 특정 문자를 배치함으로써 구현됩니다.

Basic

전형적으로, 이들 문자의 구문은 다음과 같으며, <를 사용하여 입력을 리다이렉션하고, >를 사용하여 출력을 리다이렉션합니다. command > file1는 command을 실행하여 출력을 표준 출력에 대해 보통의 대상인 터미널에 표시하는 것과는 대조적으로 file1에 출력을 배치합니다. 이것은 file1에서 임의의 존재하는 데이터를 지워버릴(clobbering) 것입니다.

command < file1을 사용하면 표준 입력에 대해 보통의 소스인 키보드와 달리 file1을 입력 소스로 갖는 command을 실행합니다.

command < infile > outfile는 두 능력을 결합니다: commandinfile에서 읽고 outfile에 씁니다.

Variants

파일을 지워버리는 대신에 파일의 끝에 출력을 덧붙입니다: >> 연산자가 사용됩니다: command1 >> file1.

스트림 리터럴 (표준 입력에 전달된 인라인 파일)에서 읽기 위해, 우리는 << 연산자를 사용하여 여기 문서를 사용할 수 있습니다:

$ tr a-z A-Z << END_TEXT
> one two three
> uno dos tres
> END_TEXT
ONE TWO THREE
UNO DOS TRES

문자열을 읽기 위해, 우리는 <<<를 사용하여 여기 문자열을 사용할 수 있습니다: tr a-z A-Z <<< "one two three", 또는:

$ NUMBERS="one two three"
$ tr a-z A-Z <<< "$NUMBERS"
ONE TWO THREE

Piping

명시적 중간 파일에 대해 필요없이 한 프로그램이 또 다른 프로그램에서 출력을 읽음을 만족하는 프로그램을 함께 실행할 수 있습니다. command1 | command2는 command2에 대해 입력으로 그것의 출력을 사용하여 command1을 실행합니다 (공통적으로 파이핑이라고 불리우며, 이때 "|" 문자는 "파이프"로 알려져 있습니다).

명령을 수행하는 두 프로그램은 작업 버퍼 (리눅스는 각 버퍼에 대해 최대 64K를 허용함) 더하기 각 명령의 처리에 필요한 작업 공간이 있는 유일한 저장 공간과 병렬로 실행할 수 있습니다. 예를 들어, "정렬" 명령은 모든 입력 레코드가 읽힐 때까지 임의의 출력을 생성할 수 없는데, 왜냐하면 수신된 가장 마지막 레코드가 정렬된 순서에서 첫 번째 레코드로 판명될 수 있기 때문입니다. Alexia Massalin 박사의 실험적 운영 시스템, Synthesis는 입력과 출력 버퍼의 채워짐에 따라 그것들이 실행할 때 각 작업의 우선 순위를 조정합니다.

이것은 다음과 같이 두 개의 리다이렉션과 임시 파일을 사용하는 것과 같은 최종 결과를 생성합니다:

$ command1 > tempfile
$ command2 < tempfile
$ rm tempfile

그러나 여기서, command2command1이 완료될 때까지 실행을 시작하지 않고, 중간 결과와 각 작업에 필요한 작업 공간을 유지하기 위해 충분히 큰 스크래치 파일이 요구됩니다. 하나의 예제로서, 비록 DOS는 "파이프" 구문을 허용하지만, 그것은 이 두 번째 접근 방식을 사용합니다. 따라서, 장기 실행 프로그램 "Worker"가 작동하면서 다양한 메시지를 생성하고 두 번째 프로그램, TimeStamp가 각 레코드를 stdin에서 stdout으로 복사하고, 레코드가 수신될 때 시스템의 날짜와 시간이 접두사로 붙는다고 가정합니다. Worker | TimeStamp > LogFile.txt와 같은 시퀀스는 Worker가 완료되었을 때만 타임스탬프를 생성하여, 그것의 출력 파일이 얼마나 신속하게 읽히고 쓰일 수 있는지 보여줍니다.

명령 파이핑에 대해 좋은 예제는 echo를 또 다른 명령과 결합하여 비대화형 쉘에서 대화형 작업, 예를 들어 echo -e 'user\npass' | ftp localhost를 수행하는 것입니다. 이것은 user를 입력하고, return을 누르고, 그런-다음 passftp 클라이언트를 실행합니다.

일상적인 사용에서, 파이프라인의 처음 단계는 종종 파일이나 문자열에서 읽는 cat 또는 echo입니다. 이것은 종종 입력 간접 참조 또는 여기 문자열로 대체될 수 있고, 입력 리다이렉션보다 캣과 파이핑의 사용은 캣의 쓸모없는 사용으로 알려져 있습니다. 예를 들어 다음 명령은:

$ cat infile | command
$ echo $string | command
$ echo -e 'user\npass' | ftp localhost

다음으로 대체될 수 있습니다:

$ command < infile
$ command <<< $string
$ ftp localhost <<< $'user\npass'

echo가 종종 쉘-내부 명령이기 때문에, 그것의 사용은 외부 명령인 캣만큼 비판적이지 않습니다.

Redirecting to and from the standard file handles

원래 본 쉘에서 파생된 유닉스 쉘에서, 처음 두 동작은 character문자 바로 앞에 숫자 (파일 설명자)를 배치함으로써 추가로 수정될 수 있습니다; 이것은 리다이렉션에 사용되는 스트림에 영향을 미칠 것입니다. 유닉스 표준 I/O 스트림은 다음과 같습니다:

핸들 이름 설명
0 stdin 표준 입력
1 stdout 표준 출력
2 stderr 표준 오류

예를 들어, command 2> file1는 command를 실행하여, 표준 오류 스트림을 file1으로 보냅니다.

csh (C 쉘)에서 파생된 쉘에서, 그 구문은 대신 & (앰퍼샌드) 문자를 리다이렉션 문자에 덧붙이고, 따라서 유사한 결과를 얻습니다. 이것에 대한 이유는 이름 '1'인 파일과 stdout 사이, 예를 들어, cat file 2>1 대 cat file 2>&1를 구별하기 위함입니다. 첫 번째 경우에서, stderr은 '1'이라는 파일로 리다이렉션되고 두 번째 경우에서, stderr은 stdout으로 리다이렉션됩니다.

또 다른 유용한 기능은 하나의 표준 파일 핸들을 또 다른 핸들로 리다이렉션하는 것입니다. 가장 널리 사용되는 변형은 표준 오류표준 출력으로 병합하는 것이므로 오류 메시지는 보통의 출력과 함께 (또는 대안적으로 출력으로) 처리될 수 있습니다. 예를 들어. find / -name .profile > results 2>&1는 .profile이라는 이름의 모든 파일을 찾으려고 시도할 것입니다. 리다이렉션 없이 실행되면, 그것은 stdout에 적중을 출력하고 stderr에 오류 (예를 들어, 보호된 디렉터리를 고찰할 권한이 없으면)를 출력할 것입니다. 만약 표준 출력이 파일 results로 지정되면, 오류 메시지가 콘솔에 나타납니다. 파일 results에서 적중과 오류 메시지를 모두 보익 위해, stderr (핸들 2)를 2>&1을 사용하여 stdout (핸들 1)에 병합합니다.

만약 병합된 출력이 또 다른 프로그램으로 파이프되려면, 파일 병합 시퀀스 2>&1는 파이프 기호 앞에 와야 하고, 따라서, find / -name .profile 2>&1 | less

간단하지만 POSIX를 준수하지 않는 명령, command > file 2>&1는 다음과 같습니다 (버전 4, 최종 릴리스 이전의 본 쉘, 또는 데비안/우분투에서 사용되는 표준 셸 Debian Almquist shell에서는 사용할 수 없음): command &>file or command >&file.

">" 앞에 2>&1을 사용할 수 있지만 결과는 공통적으로 잘못 이해됩니다. 그 규칙은 임의의 리다이렉션이 출력 스트림에 대한 핸들을 독립적으로 설정한다는 것입니다. 따라서 "2>&1"은 핸들 2를 핸들 1이 가리키는 어떤 핸들로 설정하며, 해당 지점은 보통 stdout입니다. 그런-다음 ">"는 핸들 1을 어떤 다른 것, 예를 들어, 파일로 리다이렉션하지만 여전히 stdout를 가리키는 핸들 2는 변경하지 않습니다.

다음 예제에서, 표준 출력은 file에 기록되지만, 오류는 stderr에서 stdout으로 리다이렉션되며, 즉, 화면으로 전송됩니다: command 2>&1 > file.

오류와 표준 출력을 모두 file에 쓰기 위해, 순서는 반대로 되어야 합니다. 표준 출력은 먼저 파일로 리다이렉션되고, 그런-다음 stderr가 추가적으로 파일을 가리키도록 이미 변경된 stdout 핸들로 리다이렉션됩니다: command > file 2>&1.

Chained pipelines

리다이렉션과 파이핑 토큰은 복잡한 명령을 생성하기 위해 함께 연결될 수 있습니다. 예를 들어, sort infile | uniq -c | sort -n > outfile는 infile의 줄을 사전순으로 정렬하고, 발생 횟수를 접두사로 붙은 고유 줄을 쓰고, 결과 출력을 숫자로 정렬하고, 최종 출력을 outfile에 배치합니다. 이러한 유형의 구성은 쉘 스크립트배치 파일에서 매우 공통적으로 사용됩니다.

Redirect to multiple outputs

표준 명령 tee는 명령에서 출력을 여러 대상으로 리다이렉션할 수 있습니다: ls -lrt | tee xyz. 이것은 파일 목록 출력을 표준 출력과 파일 xyz로 보냅니다.

External links