쿼카러버의 기술 블로그
Linux Shell Script - Redirection (>, >>, 2>&1) (커맨드/프로그램 로그 저장) 쉬운 사용법 & 원리에 대한 이해 본문
Linux Shell Script - Redirection (>, >>, 2>&1) (커맨드/프로그램 로그 저장) 쉬운 사용법 & 원리에 대한 이해
quokkalover 2021. 7. 18. 15:10타겟 :
- 커맨드 실행 후 출력 결과를 계속해서 파일에 로그처럼 남기고 싶은 경우
- 프로그램 실행 후 출력 결과를 파일에 로그처럼 남기고 싶은 경우
- redirection에 대한 개념 이해가 필요한 경우
등을 고민하는 분은 이 글을 참고하시기 바랍니다.
읽는법 :
쉬운 사용방법만 알고 싶은 분들은 Easy Explanation파트를,
왜?How?등 디테일하게 알아보고 싶다면 하단의 Redirection in Detail 참고.
Easy Explanation
redirecting stdout stream 기호
- 기호들은 데이터의 흐름의 방향을 나타냄
>
출력(overwrite)>>
출력(append)
overwrite (>)
stdout stream을 redirect하기 위해서는 >
or >>
기호를 쓸 수 있음.
output > file.txt
- Redirect the output (stdout) to
file.txt
file.txt
가 존재하지 않으면 새로 생성함- 이미 존재하면 덮어씌워짐 (기존의 내용이 사라짐/overwrite)
append(>>)
output >> file.txt
- 출력을
file.txt
파일에 append함 (기존의 내용 뒤에 덧 붙임) - 파일이 존재하지 않는 경우 새로 생성함.
예 1) 명령어의 결과(ls *
)를 file.txt
에 남기기
=현재 디렉토리에 있는 파일 명을 file.txt
로 옮겨서 저장하기
ls * > file.txt
- 그냥
ls *
만 실행해보면 file.txt에 입력된 내용이 터미널에서 출력되지만. - 위처럼
> file.txt
를 붙일 경우 터미널에선 출력되지 않고, 모든 출력이 다 파일에 저장된다.
예 2) 특정 스크립트 실행 결과와 에러를 같은 파일에 남기기 (overwrite)
test.sh > file.txt 2>&1
예 3) 특정 스크립트 실행 결과와 에러를 같은 파일에 남기기 (append)
test.sh >> file.txt 2>&1
예 4) 특정 스크립트 실행결과(stdout)과 에러를 분리해서 저장하기
test.sh > file.txt 2> errfile.txt
예 5) stdout은 overwrite, stderr는 append하기
test.sh > file.txt 2>> errfile.txt
정리
- 프로그램의 입력(stdin), 결과(stdout), 에러(stderr) 을 파일이나 다른 스트림으로 전달할 때 사용
- program/stream to/from files (program > file)
- 프로그램 실행결과/stream을 특정 파일로
- 저장 방식
overwrite
,append
는 기호를 통해 구분
Redirection in Detail
표준 입력 / 표준 출력에 대해서
- UNIX 이전의 OS에서는 명령어를 입력하고 출력을 보기 위해서는 프로그래머가 직접 입/출력장치를 설정해야 했다.
- 하지만 Unix부터는
data stream
이라는 개념을 이용하여 프₩로그래머가 어떤 장치를 사용하는지와는 관계 없이 open, read, write을 할 수 있게 했다. 또한 자동으로 입/출력 장치를 연결하여 많은 부담을 덜게 됐다고 한다.
stream
이란 디스크상의 파일이나 컴퓨터에 연결되는 여러 장치들을 통일된 방식으로 다루기 위한 가상적인 개념이다.
- 즉, 데이터가 어디서 나와서 어디로 가는지 신경쓸 필요없이 장치, 프로세스, 파일들과 연결돼어 많은 편리성을 제공해준다.
- 프로세스가 생성되면 기본적으로 입, 출력을 위한 채널을 가지게 되는데, 이것을 standard stream이라고 한다.
Unix에서는 모든 장치를 파일로 관리한다. 즉, standard stream
도 각각 /dev/stdin
, /dev/stdout
, /dev/stderr
에 파일로 존재한다.
FD (File Descriptor)
우리가 사용하는 파일들은 우리가 알아보기 쉬운 이름으로 보여지지만, 실제 프로그램 실행시에는 FD
(File Descriptor)라는 양의 정수 번호에 의해 처리가 된다.
- 참고 : 프로그램이 수행되면 운영체제는 실행되는 프로그램에게 3개의 기본 FD를 할당한다. 그리고 프로그램이 내부적으로 다른 파일을 open하게 되면 3번째 FD를 할당한다.
- 프로그램을 작성하고 프로그램 내부에서 파일을 열게 되면 파일 디스크립터는 3부터 할당된다
redirection
redirection이란, 위 그림에서 번호로 매겨져 있는 부분을 프로그래머가 원하는쪽으로 redirect하는 것.
- FD 번호를 사용해, 화살표가 가르치는 빨간 별표 부분을 redirect 하는게 redirection
shell에서도 redirection을 할때 이와 같은 FD번호를 사용한다.
- 명령어를 실행하면
stdin
(입력),stdout
(출력),stderr
(에러 출력)이 존재하는데, - 기본적으로 shell 프로세스의
stdin
,stdout
,stderr
가 모두 터미널에 연결되어 사용자로부터 입력을 받고 출력을 해서 우리가 터미널 명령어를 편리하게 사용할 수 있는 것.
기본 사용법
아래와 같은 infile이 있다고 해보자.
$ cat infile
hello
world
그리고 위의 infile을 그대로 outfile로 옮겨적을때는 아래와 같이 하면 된다.
$ wc 0< infile 1> outfile
$ cat outfile
2 2 12
위의 wc
명령은 redirection 의 기본 사용법을 보여준다.
데이터 흐름의 방향을 나타내는 redirection 기호인 < (입력)
, > (출력)
, >> (출력:append)
을 가운데 두고
- 왼쪽에는 FD (file descriptor),
- 오른쪽에는 FD '나' filename 을 위치시키면 됩니다.
기본 값 (Default Value)
위 예시를 보면 infile을 FD 0(stdin)에 연결해서 입력으로 사용했고
FD 1 (stdout)을 outfile에 연결하여 출력이 outfile파일에 저장되게 했다.
redirection기호를 사용할 때 FD번호를 적어줘야 하지 않으면 적어주지 않을 경우에는 standard stream
이 사용된다.
<
의 좌측 기본 값 = 0>, >>
의 좌측 기본값 = 1
따라서
$ wc < infile > outfile
$ cat outfile
2 2 12
처럼 입력해도 동일한 결과 값을 가져옴.
주의 사항
<
, >
, >>
기호 좌측값은 공백없이 붙여야한다. 그렇지 않으면 명령의 인수로 인식이 되기 때문에 주의해야 한다..
$ wc 0 < infile 1> outfile # 0 을 wc 명령의 인수로 인식.
wc: 0: No such file or directory
$ wc 0< infile 1 > outfile # 1 을 wc 명령의 인수로 인식.
wc: 1: No such file or directory
>
, >>
기호의 우측값은 파일이름이 올경우는 괜찮지만
- FD 번호가 올경우는
&
기호를 붙여줘야 한다. - 그렇지 않으면 FD 숫자가 파일이름이 된다.
>&2 , 2>&1, 1>&2들의 의미
>&2
,2>&1
,1>&2
등은 위에서 설명했듯이,기호 오른쪽에 파일이름이 아닌 FD번호를 쓰고 싶을때 &를 사용해서 표현한 기호들이다.
헷갈리는 케이스 1)
아래 명령어가 의미하는건 → 1이라는 파일로 asdfgh의 파일 내의 내용을 입력하는 것.
$ wc asdfgh 2>1
$ cat 1
wc: asdfgh: No such file or directory
- 오른쪽에 &를 붙이지 않아서, 파일 이름으로 인식한 것
- 따라서 에러 출력이 파일 1로 가게 됨.
헷갈리는 케이스 2)
$ wc asdfgh 2>&1
wc: asdfgh: No such file or directory
- stdout을 stderr로 redirect 하겠다는 의미가 됨.
- 그럼 위 명령어를 실행하면 FD
1
의 경우 현재 shell을 가리키고 있기 때문에 에러를 터미널에 출력하라는 것과 동일한 의미.
- 그럼 위 명령어를 실행하면 FD
- 자 이해안되면 아래를 잘 읽어야 이해된다.
- 위 커맨드를 실행시, asdfgh 라는 파일이 없기 때문에 stderr가 출력될텐데
- 해당 내용을 &1(stdout)으로 넘기는데, 현재는 "터미널창으로 가리키고 있기 때문"에 터미널 창에 에러 메시지가 출력이 됨.
>&
as 'redirect merger operator' 라고 생각하면 됨.- 즉
2>&1
= 2> redirect stderr to a file,를 의미하고 &1를 추가해서 stderr를 stdout로 머지시키는 것.
- 즉
자주 사용하는 케이스
만약 특정 명령어의 결과를 특정 파일에 넣고싶고, 에러도 같은 파일에 넣고 싶으면 두 가지 방법이 있음.
$ wc asdfghh > tmpfile 2>&1
$ wc asdfghh 1> tmpfile 2> tmpfile #위와 동일함.
- 위처럼 하면 &1이 현제 tmpfile로 지정됐기 때문에 err도 tmpfile로 넘어감.
만약에 stdout과 stderr를 나누고 싶다면 아래처럼 하면 됨
{명령어, 프로그램} 1>{stdout file이름} 2>{stderr 지정할 파일 이름}
stdout만 출력하고 싶으면
{명령어, 프로그램} 1>{stdout file이름} #or
{명령어, 프로그램} >{stdout file이름}
- 이렇게 하면 정상 출력은 {stdout file 이름}으로 들어가고 stderr는 터미널에서 출력됨.
참고 자료
https://stackoverflow.com/questions/9553628/piping-and-redirection
https://twpower.github.io/133-difference-between-redirect-and-pipe
https://www.linuxunit.com/io-redirection-stdin-stdout-stderr-streams/
https://mug896.github.io/bash-shell/redirections.html
https://stackoverflow.com/questions/818255/in-the-shell-what-does-21-mean
'Linux - Ubuntu > Shell Script' 카테고리의 다른 글
[Linux] sed - 리눅스 명령어 sed에 대해서 (1) | 2021.08.18 |
---|---|
Linux Shell Script - find (리눅스에서 파일, 디렉토리 찾는 법) (0) | 2021.07.22 |
Linux Shell Script - Pipe ( | ) (리눅스에서 파일 검색법, cpu 모델명 찾기 등) 쉬운 사용법 & 원리에 대한 이해 (0) | 2021.07.18 |
Linux Shell Script - while 문 (반복문) (테스트 스크립트 반복 실행하고 싶을 때 등) (0) | 2021.07.18 |
Linux Shell Script - IF 문, 다양한 연산자들(-d, -eq, -a)(디렉토리가 존재하는지 확인하고 싶을 때 등) (0) | 2021.07.18 |