2013 이전/기타

[UNIX] cat 리다이렉션 주의 사항

하구루 2017. 2. 25. 16:43

간단한 파일 입출력을 위해서 cat을 이용하는 경우가 종종 있을 것이다. 간단한 명령어기 때문에 별 생각 없이 써왔던 명령어였는데, 실수를 통해서 좀 깊이 알게되어 정리 해보려 한다.


 내가 했던 실수는 다음과 같다.
 
 test1.txt 와 test2.txt의 내용을  test3.txt에 저장하려고 하였다.
그런데 실수로 아래와 같이 해버렸다.

$cat test* > test3.txt

위 문장은 풀어서 쓰면 다음과 같다

$cat test1.txt test2.txt test3.txt > test3.txt

 위처럼 자기 자신 까지 포함해서 test3.txt에 저장이 되게 한 것이다. 그래도 test3.txt가 내용이 존재 하지 않기때문에 별 문제없을 것이라고 생각했다. 그런데, 신기하게도 무한 루프가 걸리면서 test1과 test2의 내용이 반복해서 test3.txt에 저장되고 있었다. 무슨일이 일어난 것일까?
 대충 생각하면, 자기자신에게 저장이 되다보니 그럴수도 있을것 같은데, 명확한 이유를 알고 싶었다. 직접 cat명령어의 소스도 찾아서 분석하고, Linux를 잘다루는 친구에게 물어봐가며 어럽게 답을 찾아 내었다.

 cat의 input output 방식의 문제이다. cat에서는 파일을 읽을때, 일정한 byte를 메모리에 읽어와서 파일에 쓰고, 그 나머지를 다시 읽어와서 파일에 쓰는 방식이다. 요쯤 되면 조금 감이 잡히는 분도 있을 것이다. 위의 예로 적용하면 test1.txt test2.txt test3.txt의 내용을 일정 byte를 메모리로 가져와서 test3.txt에 저장을 하게 된다. 그리고 다시 cat은 가져온 일정 byte이후의 내용을 확인하고 가져오려고 할것이다. test1.txt와 text2.txt의 내용은 더 이상 가져올 것이 없으므로 이대로 끝이다. 하지만 test3.txt는 다르다. 방금 test1.txt와 test2.txt의 내용이 써졌기 때문에 처음에 가져왔던 byte(파일이 새로 만들어지기 때문에 0byte) 이후의 내용이 존재한다. 그래서 이를 가져와서 다시 test3.txt에 쓰게 된다. 그러면 또 다시 test3.txt의 내용이 늘어나고 이전에 썻던 byte이후의 내용이 존재하여 이를 계속 반복하게 된다.
 cat이 한꺼번에 모든 파일의 내용을 읽어 올 수 없기 때문에, 일정 byte씩 읽어 와서 일어나는 현상이다.

 그리고 참고로, 위에서도 잠깐 언급했지만 일반적인 '>' 의 리다이렉션은 항상 결과 파일을 새로 생성한다. 그리고 그 생성하는 타이밍은 파일을 읽어서 메모리에 올리기전 가장 먼저 수행된다.
 이를 확인 할수 있는 예로
 test1.txt에 "test1.txt 파일입니다" 라는 내용이 있다고 해도,
 
$cat test1.txt > test1.txt

위와 같이 수행하면 test1.txt의 내용이 사라진다. test1.txt의 내용이 메모리에 올라가기 전에 test1.txt의 파일이 새로 생성되기 때문에 파일은 비어져 버리고 이를 test1.txt에 쓰게 되기 때문에 비어지게 된다.

위 두가지의 cat의 특성만 알더라도 사용하는데 좀더 도움이 되지 않을까 싶다.


반응형