1. 개요
NAME
cat - concatenate files and print on the standard output
여러 입력을 표준 출력으로 이어주는 UNIX 명령어. 이름의 유래는 연결하다, 결합하다 등을 뜻하는 (con)catenate.[1]
2. 용도
본래 용도는 2개 이상의 파일을 서로 이어 붙여 하나로 만들기 위한 파일 병합 명령이다. 이름 그대로 catenate의 역할이다.#!syntax sh
$ cat a.txt b.txt c.txt > all.txt
위와 같이 실행하면 a.txt b.txt c.txt 파일의 내용을 모두 붙여서 all.txt 파일을 생성한다. 이게 원래의 용도이다.#!syntax sh
$ cat a.txt b.txt c.txt
별도의 리다이렉션 없이 실행하면 3개의 파일을 모두 표준 출력(stdout)에 출력한다.#!syntax sh
$ cat a.txt
그런데, 인자를 하나만 주어도 되고, 이렇게 실행하면 a.txt 파일 내용을 stdout에 출력한다. 간단하게 터미널에서 파일 내용을 볼 수 있기에 실제로는 이 용도로 더 많이 사용된다.#!syntax sh
$ cat
아무 인자 없이 cat
을 실행하면 기본적으로 표준 입력(stdin)에서 내용을 읽는다.[2] 또한 기본 출력은 표준 출력을 향하므로 입력받은 내용을 그대로 출력할 것이다. 위와 같이 cat
을 실행한 다음 아무 글자나 치고 엔터를 눌러 보자. 메아리처럼 방금 입력한 문장이 그대로 돌아올 것이다.#!syntax sh
$ cat > new.txt
기본 출력을 리다이렉션하면 입력한 내용을 원하는 곳으로 보낼 수도 있다. 위와 같이 입력하고 원하는 글을 쓴 다음 Ctrl
+ D
(EOF)를 누르면 작성한 글이 new.txt로 저장된다.#!syntax sh
$ cat a.txt | cat | cat | cat | cat | cat
기본적으로 입력을 출력으로 연결해준다는 점을 응용하면 파이프를 통해 수많은 유닉스 명령어들과 기발하게 조합할 수 있다. 물론 위와 같이
cat
을 쓸데없이 남용하는 사례를 Useless use of cat(UUOC)이라고 부르며 리다이렉션과 각 명령어 옵션을 조합하는 것이 좋긴 하지만 shell golf를 치는 게 아닌 이상 파이핑에서 cat이 직관적으로 쓰이는 경우도 많다.[3]2.1. 일반적인 용도
주로 짧은 텍스트 파일의 내용을 화면에 출력해주는 용도로 많이 쓰인다. 소스 코드를 보는 경우, 줄 번호를 표시하도록 설정할 수도 있다.하지만, 리눅스 VT등 스크롤백을 지원하지 않는 구식 터미널 에뮬레이터라면 파일의 후반부만 잘려서 보이고 설령 스크롤이 가능하더라도 파일의 내용이 길면 보기가 어렵다. 게다가 텍스트 파일이 아닌 바이너리 파일을
cat
하면 파일 내용을 있는 그대로 화면에 뿌려 버리기 때문에 터미널 에뮬레이터가 무의미한 바이트를 ANSI 이스케이프 코드나 특수 문자로 인식해 버려 화면이 왕창 깨져 버린다. 그래서 유닉스/리눅스에 익숙한 유저들은 more
또는 less 등의 pager를 사용해 파일을 읽는다.3. 옵션
아래 옵션은 대부분의 배포판에서 쓰이고 있는 GNU coreutils의 man page를 기준으로 한다. 특수한 배포판이나 구현체에 따라 미세하게 다를 수 있음에 주의.축약 | 전체 | 비고 |
-A | --show-all | -vET 와 동일. 주로 모든 종류의 특수문자를 전부 표시하고 싶을 때 사용한다. |
-b | --number-nonblank | 비어있지 않은 모든 줄에 1부터 시작하는 행 번호를 표시한다. cat ... | nl 과 동작이 비슷하다. |
-e | -vE 와 동일. | |
-E | --show-ends | CRLF 디버깅을 위해 쓸 수 있는 옵션으로, LF는 $ , CRLF는 ^M$ 로 표시한다. |
-n | --number | 모든 줄에 1부터 시작하는 행 번호를 표시한다. cat ... | nl -b a 와 동작이 비슷하다. |
-s | --squeeze-blank | 반복된 공백을 공백 하나로 표시한다. 들여쓰기가 너무 길거나 라이선스 파일처럼 고정폭 정렬이 되어있는 문서를 볼 때 유용하다. |
-t | -vT 와 동일. | |
-T | --show-tabs | 탭 문자를 ^I 로 표시한다. -s 와 마찬가지로 들여쓰기 시각화에 유용한 옵션. |
-u | POSIX 표준 구현체 기준, 입력 버퍼를 사용하지 않고 즉시 flush한다. | |
-v | --show-nonprinting | LF와 탭을 제외한 특수 문자를 캐럿 인코딩으로 보여준다. |
몇몇 옵션들은 화면에 표시할 수 없거나 화이트스페이스인 글자를 아스키로 치환해서 보여준다. 상술한 예시와 같이 바이너리를 펼쳐볼 때 화면이 망가지는 것을 막을 수 있으며, grep등을 사용한 검색 등에도 유용해진다.
4. 파생 명령어
워낙 기본적이고 자주 쓰는 명령어인 동시에 유닉스의 철학을 가장 잘 보여주는 예시라는 상징성, 동시에 너무 단순한 기능으로 인해 사용성이 떨어지는 점도 겹쳐져 여러 파생 소프트웨어를 탄생시켰다. 대부분 -cat 형태의 이름을 가지는 것이 특징.netcat
: 축약어인nc
로 배포되는 경우도 많으며, 'Swiss-army knife for TCP/IP'라는 별명에 맞게 주로 TCP(또는 UDP)로 특정 프로세스에 접속해 raw 디버깅을 할 때 사용된다. 응용만 하면 간단한 채팅 프로그램을 만들거나 TCP 프록시/멀티플렉서를 만들 수도 있지만socat
등에 비하면 조금 부족한 편.socat
: TCP/UDP 및 표준 입출력 파이핑밖에 할 수 없는 netcat에 비해 유닉스 소켓, SSL, 시리얼 커넥션, 클라이언트 포크 기능 등을 지원한다.#tac
:cat
과 같이 입력을 읽고 표준 출력으로 내보내지만 순서를 전부 거꾸로 한다. 이름부터 cat을 거꾸로 한 tac. GNU coreutils에 포함되어 있다.zcat
: gzip 압축된 파일을 주로 파이핑을 통해 plaintext로 읽기 위해 쓰이는 명령어. 동작 자체는gunzip -c
와 동일하다.bzcat
: 위 zcat과 비슷하게 bzip2 포맷 압축 해제를 위한 CLI.xzcat
: xz 압축 알고리즘 zcat.lolcat
: 출력을 아주 다채롭게 꾸며주는 명령어. 이름의 유래는 영미권의 유명한 밈인 LOLcat.kcat
: 메시지 큐 프로토콜인 아파치 카프카의 디버깅용 컨슈머/프로듀서로 쓰일 수 있는 CLI.bat
: Rust로 작성한 구문 강조를 지원하는 cat. mandoc pager로도 쓸 수 있는데 이때 이름이 batman(...)이다. 구문 강조 라이브러리로 syntect를 사용하는데 이는 Sublime Text 자체 구문 강조 포맷과 호환된다.ccat
: bat과 비슷하게 구문 강조 지원 cat으로, 소스그래프의 syntaxhighlight 패키지가 제공하는 HTML 컬러 마크업을 ANSI로 변환하는 방식으로 구현된다. 지원되는 언어가 매우 한정적인 편.dircat
: 디렉토리 내에 있는 모든 파일을 재귀적으로cat
하는 프로그램. 원래 cat의 용도와 매우 비슷하다.
[1] "Catenate" is an obscure word meaning "to connect in a series", which is what the cat command does to one or more files. #[2] 배포판에 따라
-
를 표준 입력 fd(stdin fd)로 인식하는 경우도 있다.[3] Also, it can be easier to conceptualize the stream moving left to right. #