안녕하세요. 코딩개입니다. 이번 시간에는 tee 명령어에 대해 간단하게 알아보겠습니다.

 


 명령 설명을 보겠습니다. standard input으로부터 읽고, 파일과 standard output으로 떨군다. 그림으로 도식화 시키면 아래와 같습니다. 아마 많이들 보셨을 겁니다.

 

 마치 이것이 T처럼 생겨먹었습니다. 그래서 tee라고 부르나 봅니다. 파이프랑 같이 많이 쓰일 수 있습니다. 예를 하나 들어보겠습니다.

 

 저는 12345를 1.txt, 2.txt, 3.txt에 저장하려고 합니다. 이럴 때, echo 12345를 한 결과를 tee의 입력으로 받습니다. 그리고 tee 뒤에 1.txt, 2.txt, 3.txt를 넣었는데요. 이는 output을 떨굴 파일이 1.txt, 2.txt, 3.txt라는 의미입니다. 확인은 어떻게 하면 될까요? 1.txt와 2.txt, 3.txt의 내용을 cat 명령어로 확인해 봅시다.

 

 12345가 잘 들어갔음을 볼 수 있습니다.

 

 

 -a 옵션을 넣으면 overwrite가 아니라 append 됩니다. 위에서 아무 옵션 없이 tee를 썼으므로, 1.txt와 2.txt, 3.txt는 12345가 들어가게 됩니다. 다음에 -a옵션을 넣은 12345가 입력되었으므로, 12345가 2개의 줄에 걸쳐서 각각의 텍스트 파일에 저장됩니다.

 


그러면, tee 1.txt 2.txt 3.txt가 어떻게 동작할까요? strace 명령어를 통해서 어떤 system call 함수를 호출하나 봅시다.

 

 

뭔가 매우 많은 함수들이 슈슈슉 하고 지나갑니다만, 표준 입력에서 받기 때문에 strace는 어디선가 멈출 겁니다. 계속 입력을 받다가, 파일의 끝을 만나면 break를 걸 겁니다.

 

 

 alra를 입력하고 ctrl + D를 누르면, close(3), close(4), close(5), close(0), close(1), close(2)가 호출되면서 종료되는데요.

 

 3번 디스크립터는 1.txt를 보고 있고, 4번은 2.txt를, 5번은 3.txt를 보고 있습니다. 이는 openat 함수의 리턴값을 보면 알 수 있습니다. write(3, "alra\n", 5)는 3번이 가리키고 있는 파일에 내용 "alra\n"를 쓰라는 말입니다. 즉, 1.txt, 2.txt, 3.txt를 열어서 디스크립터를 할당한 다음에, 해당 디스크립터에 stdin으로 입력한 것을 쓴다. 정도로 해석하면 됩니다.

 

 이제 echo 12345 | tee ... 는 어떨까요? 위와 다른 점은 pipe가 있다는 점입니다.

 

 

  그림으로 그리면 이런 상황인데요. echo 12345의 결과는 12345입니다. 이것이 stdout으로 가는데, 요게 tee와 파이프 처리가 되어 있습니다. 따라서, tee의 입력으로 가 버립니다. 이제 12345라는 입력이 파일 3개와 표준 출력 (stdout)에 출력되게 됩니다.