WAS Engineer - Linux 5번째

이정빈·2022년 9월 20일
0

리눅스 복습

목록 보기
5/11
post-thumbnail

표준 입출력

표준 입출력 채널은 다음과 같은 세 가지가 있다.

  • 표준 입력(stdin): 프로그램에 데이터를 입력하는 채널. 키보드 입력 등
  • 표준 출력(stdout): 프로그램 실행 결과가 출력되는 채널. 단말 디스플레이 등
  • 표준 에러 출력(stderr): 프로그램 실행 중 발생하는 에러 메시지가 출력되는 채널. 단말 디스플레이에 출력

이 세 채널을 합쳐 표준 입출력이라고 한다.

리다이렉션

  1. 표준 입력의 리다이렉션

키보드 대신 파일을 표준 입력으로 연결. 이를 입력 리다이렉션이라고 하며 기호로 <를 사용한다.

입력 리다이렉션과 파일 지정

cat 명령어로 파일 내용을 출력하는 방법은 두 가지이다.

cat < /etc/crontab <- 입력 리다이렉션 사용
cat /etc/crontab <- 인자로 파일 지정

두 방식의 출력 결과는 같지만, 내부적인 차이점을 이해해야 한다.

리다이렉션을 사용한 경우는 '표준 입력을 읽어서 표준 출력에 그대로 출력한다'는 cat 명령어의 기본 동작에 충실한 방식이다. 한편 파일을 실행 인자로 지정하는 방식은 사용자의 편의를 위해 cat 명령어가 특별히 제공하는 방식을 사용한 것이다.

  1. 표준 출력의 리다이렉션

표준 출력도 리다이렉션 할 수 있다. 자주 사용되는 패턴은 명령어의 실행 결과를 화면에 출력하는 것이 아니라 파일에 지정하는 것이다. 표준 출력의 기호는 >이다.

  • ls 명령어의 결과를 파일에 저장

$ ls -l>list.txt <-명령어의 실행 결과를 list.txt에 리다이렉션

리다이렉션된 파일은 자동적으로 만들어진다.

  1. 표준 에러 출력

표준 에러 출력은 프로그램의 에러 메시지를 출력하기 위해 사용된다. 예를 들어 ls 명령어를 실행할 때 존재하지 않는 파일을 지정하면 에러메시지가 출력되는데, 이 메시지는 표준 에러 출력에 출력된 것이다.

  • 명령어의 에러 메시지는 표준 에러 출력에 출력된다

$ ls /xxxxx
ls: '/xxxxx'에 접근할 수 없습니다: 그런 파일이나 디렉터리가 없습니다

표준 출력을 파일에 리다이렉션해 보면 그 차이를 알 수 있다

표준 에러 출력을 파일에 리다이렉션할 수 있다. 이때는 2>라는 기호를 사용해야 한다

명령어의 실행 결과와 에러 메시지를 별도로 다루기 위해 표준 출력과 표준 에러 출력이 별도 존재한다

  1. 표준 출력과 표준 에러 출력을 함께 리다이렉션

표준 출력과 표준 에러 출력을 파일 하나에 리다이렉션할 때도 있다. 이때는 표준 출력을 리다이렉션한 뒤에 2>&1을 붙여주면 된다.

  • 표준 출려과 표준 에러 출력 둘 다 result.txt로 리다이렉션하는 예

    $ls /xxxxx > result.txt 2>&1

  • 표준 입출력에 매핑된 숫자

입출력 채널숫자
표준 입력0
표준 출력1
표준 에러 출력2

위 표와 같이 리눅스에서는 내부적으로 표준 입출력을 숫자로 관리하고 있다. 그래서 1이 의미하는 것은 표준 에러 출력(2)를 표준 출력(1)과 같은 파일로 리다이렉션한다는 뜻이다.

  1. 리다이렉션으로 파일 덮어쓰기

이미 존재하는 파일에 표준 출력을 리다이렉션하면 기존 파일을 지우고 덮어쓰게 된다.

따라서 리다이렉션으로 인해 중요파일을 분실하는 경우가 있다. 이를 방지하기 위해 > 대신 >>를 사용하면 덮어쓰지 않고 파일에 끝에 이어서 기록하게 된다.

또 다른 방법으로는 셸 옵션으로 noclobber라는 값을 set 명령어로 지정하는 것이 있다.

  1. /dev/null

리눅스를 다루다 보면 종종 /dev/null이라는 파일에 리다이렉션할 때가 있다. 먼저 ls 명령어로 /dev/null이란 파일이 있는지 확인한다.

$ ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 5월 16 18:40 /dev/null

/dev/null은 특수 파일로서 다음 특성을 가진다

  • 입력 파일을 지정해도 아무 내용도 입력되지 않는다
  • 출력 파일로 지정해도 어떤 내용도 기록되지 않는다

예를 들어 다음과 같이 /dev/null을 표준 입력으로 리다이렉션하면 아무 내용도 입력되지 않아서 아무 내용도 출력되지 않는다

  • 빈 내용의 표준 입력

$ cat < /dev/null
$ <- 아무것도 표시되지 않음

명령어의 실행 시간을 확인하거나 굳이 출력되는 메시지를 확인하지 않아도 될 때 이 방식을 사용한다

파이프라인

여러 명령어를 연결하려면 한 명령어의 실행 결과를 다른 명령어에 입력할 수 있어야 한다. 이를 위해 존재하는 기능이 파이프라인이다. 파이프라인을 사용하면 명령어의 표준 출력을 다른 명령어의 표준 입력으로 연결할 수 있다.

파이프라인을 사용하면 중간에 파일을 만들지 않고도 명령어의 실행 결과를 다른 명령어에 전달할 수 있다.

파이프라인은 파이프 기호(|)를 사용한다.

  • 파이프라인

<명령어 1> | <명령어 2> [| <명령어 3>] ...

그러면 첫 번째 명령어의 표준 출력이 두 번째 명령어의 표준 입력으로 전달된다

필터 명령어

표준 입력으로 받아들여 표준 출력으로 출력하는 명령어를 필터 명령어라 한다

  1. 필터 명령어의 예: head 명령어

대표적인 필터 명령어로 head가 있다. head는 지정한 파일의 첫 행부터 지정한 행까지 출력한다. 이 때 출력할 행 수를 지정하지 않으면 첫 10행을 출력한다. 다음은 head 명령어로 /etc/crontab의 첫 10행을 출력하는 예이다.

  • 파일의 첫 10행을 출력

$ head /etc/crontab

head 명령어를 사용할 때 입력 파일을 지정하지 않으면 표준 입력을 입력으로 사용한다. 즉, head 명령어는 필터 명령어이다. 다음과 같이 head 명령어와 history 명령어를 파이프라인으로 연결하면 명령어 이력의 첫 10행만 출력할 수 있다.

  • 명령어 이력의 첫 10행만 출력

$ history | head

기본적으로 필터 명령어는 파이프라인과 함께 많이 사용한다.

  1. 대표적인 필터 명령어

리눅스에 있는 대표적인 필터 명령어는 다음과 같다.

명령어역할
cat입력 내용을 그대로 출력
head파일 앞부분을 출력
tail파일 뒷부분을 출력
grep검색 패턴에 일치하는 행을 출력
sort정렬
uniq중복된 행을 제거하여 출력
tac역순으로 출력
wc행 수나 바이트 수를 출력
  1. 명령어 조합

필터 명령어는 파이프라인을 사용하여 다른 명령어와 조합할 때 그 진가가 발휘된다.

/bin 디렉터리에 있는 파일을 크기가 큰 순서대로 출력하고 싶은 경우를 생각해 보겠다.

먼저, 파일의 크기를 출력하는 명령어로는 du가 있다.

  • 파일이나 디렉터리의 크기를 출력

du [옵션][파일/디렉터리]

du 명령어에 b 옵션을 지정하면 파일 크기를 바이트 단위로 출력한다. 다음 예는 /bin 디렉터리 아래의 모든 파일의 크기를 출력한다.

  • du 명령어로 파일 크기 출력

du -b /bin/*

이제 이 결과를 크기순으로 정렬한다. 리눅스에서는 sort 명령어를 사용해 결과를 정렬할 수 있다. sort 명령어를 사용할 때 아무 옵션도 지정하지 않으면 알파벳 순으로 정렬한다. 숫자를 기반으로 정렬하려고 하니 -n 옵션을 추가해야 한다.

다음은 du 명령어의 출력 결과를 sort 명령어로 정렬하고 있다.

  • 파일 크기가 작은 순으로 정렬하여 출력

$ du -b /bin/* | sort -n

파일 크기가 작은 것부터 차례로 출력된다.

위와 같이 각 필터 명령어는 단순한 기능을 수행하지만 파이프라인으로 연결함으로써 좀 더 고도의 기능을 수행할 수 있다.

텍스트 처리

wc 명령어: 바이트 수, 단어 수, 행 수 세기

wc 명령어에 옵션을 지정하지 않으면 행 수, 단어 수, 바이트 수를 차례대로 출력한다.

그리고 -l, -w, -c 옵션을 지정하면 각각 행 수, 단어 수, 바이트 수만 출력한다.

sort 명령어: 행 단위로 정렬하기

sort 명령어는 행 단위로 정렬하여 결과를 출력. 정렬이란 특정 기준에 맞춰 요소를 나열하는 것을 말한다. 아무 옵션을 지정하지 않으면 sort는 알파벳순으로 정렬됨.

sort 명령어는 기본적으로 각 행의 첫 글자부터 마지막 글자까지를 기준으로 정렬하지만 각 행의 특정 항목을 기준으로 정렬하는 것도 가능하다.

  1. 숫자 값으로 정렬 (-n)

-n 옵션은 문자열을 숫자 값으로 인식하고 정렬하는 옵션이다.

  1. 역순으로 정렬 (-r)

sort 명령어를 사용할 때 -r 옵션을 지정하면 역순으로 정렬된다. sort 명령어는 기본적으로 알파벳 오름차순으로 정렬하므로 역순(-r)일 때는 알파벳 내림차순으로 정렬하게 된다.

-n과 -r 옵션을 함께 지정하면 숫자 값이 큰 순으로 정렬된다.

uniq 명령어: 중복 제거하기

uniq는 연속된 중복 데이터를 하나만 출력하는 명령어이다.

하지만 같은 내용이 연속되어 있는 경우에만 중복 데이터를 제거한다. 즉, 연속되지 않은 중복 데이터는 없애지 않는다.

이 때, sort 명령어로 정렬한 뒤에 uniq 명령어를 실행하면 파일 전체에서 중복을 전부 없앨 수 있다.

sort 명령어에도 중복된 데이터를 한 번만 표시하는 -u 옵션이 있다. 이 옵션을 사용해도 중복을 없앨 수 있다.

  1. 중복 데이터의 개수 세기

uniq 명령어의 옵션 중에서 활용도가 높은 -c 옵션은 중복된 데이터의 개수를 알려준다.

cut 명령어

cut 명령어는 입력의 일부를 추출하여 출력하는 명령어이다.

  • 입력의 일부를 추출하여 출력

cut -d <구분자> -f <필드 번호> [<파일 이름>]

cut은 <구분자>로 지정한 문자를 기준으로 입력 데이터를 분할하여 그 중에서도 <필드 번호>로 지정한 필드만 출력한다.

예를 들어 -d, -f 3 같이 지정하면,를 기준으로 분할하여 3번째 필드만 출력한다. 이러한 cut 명령어를 csv파일의 특정 컬럼만 출력할 때 사용할 수 있다.

cut -d, -f 3 file.csv

d로 구분자를 지정하지 않으면 기본으로 탭이 사용된다.
출력할 필드는 쉼표를 사용하여 여러 개를 지정할 수 있다.

tr 명령어:문자 교환과 삭제하기

tr은 문자를 치환하는 명령어이다.

  • 입력 문자를 치환

tr <치환 전 문자> <치환 후 문자>

문자 여러개를 동시에 바꾸는 것도 가능하다.

cat /etc/passwd | tr abc ABC

여기서 abc라는 문자열을 ABC로 바꾼 것이 아니라 a,b,c 각 문자를 A,B,C로 바꾼 것에 주의해야 한다.

또한, 하이픈(-)으로 치환할 문자의 범위도 지정할 수 있다. 예를 들어 a-g는 abcdefg와 같은 의미를 가진다.

tr 명령어는 문자 단위의 치환 명령어이다. 문자열 단위로 치환하고 싶을 때는 sed나 awk 명령어를 사용하면 된다.

  1. 파일은 지정할 수 없다

지금까지의 필터 명령어들은 파일을 지정하지 않으면 표준 입력을 읽고, 지정하면 해당 파일을 읽었다. 하지만 tr 명령어는 표준 입력만 받아들이도록 설계되었다.

그래서 파일을 지정할 수 없다. 텍스트 파일에 tr 명령어를 실행하려면 파이프라인으로 전하거나 입력 리다이렉션해야 한다.

  1. 문자 삭제하기
  • tr 명령어로 문자 삭제

tr -d <삭제할 문자>

tr 명령어로 문자를 지우는 것은 개행문자를 전부 없앨 때 자주 사용한다. 다음과 같이 -d 옵션으로 개행무자 \n을 지정하면 개행문자를 전부 지우고 한 행으로 만들 수 있다.

tail 명령어: 마지막 부분 출력하기

tail은 파일의 마지막 부분을 출력하는 명령어이다. 옵션을 지정하지 않으면 마지막 10행을 출력한다.

-n 옵션으로 출력할 행 수를 지정한다.

  • 마지막 한 행을 출력

$ tail -n 1 /etc/passwd

tail의 반대로 동작하는 명령어가 head이다. head도 기본으로 첫 10행을 출력하고 -n 옵션으로 몇 행을 출력할지 지정한다.

  1. 파일 모니터링하기

어플리케이션의 로그처럼 파일 내용이 계속해서 추가되는 경우에는 tail의 - f 옵션을 사용하면 된다. 추가될 때마다 실시간으로 내용을 출력하여 파일을 모니터링 할 수 있다.

  • tail 명령어로 파일 내용을 모니터링

tail -f <파일 이름>

리눅스를 운영할 때에는 로그 파일을 실시간으로 모니터링하는 경우가 많다.

diff 명령어: 차이 출력하기

diff 명령어는 두 파일의 차이점을 출력한다.

  • 파일 비교

diff [옵션] <비교 파일 1> <비교 파일 2>

소스 코드나 설정 파일의 편집 전과 후의 차이점을 확인할 때 이 명령어를 자주 사용한다.

  • 변경 종류
기호내용
<범위 1>a<범위 2>첫 번째 파일의 '범위 1'뒤에 두 번째 파일의 '범위 2'의 내용이 추가
<범위 1>c<범위 2>첫 번째 파일의 '범위 1'부분이 두 번째 파일의 '범위 2'의 내용으로 변경
<범위 1>d<범위 2>첫 번째 파일의 '범위 1'부분이 삭제

각 행의 앞에 있는 <는 첫 번째 파일에만 있는 행을, >는 두 번째 파일에만 있는 행을 의미한다. 즉, <는 지워진 행을 의미하고 >는 추가된 행을 의미한다.

이 때 두 파일의 차이점만 표시되며 공통점은 표시되지 않는다. 따라서 두 파일이 완전히 같은 내용이라면 아무것도 표시되지 않는다.

파일 안에서 여러 부분을 수정했으면 차이점이 범위 단위로 표시된다. 여기서 각 변경 범위를 헝크(hunk)라 부른다.

  1. 통일 포맷

diff 명령어로 차이를 출력하는 형식에는 여러 가지가 있다. 앞서 살펴본 형식은 <, >를 사용하여 표시하지만 그 외에도 자주 사용되는 형식으로 통일 포맷(unified format)이 있다.

diff 명령어를 실행할 때 -u 옵션을 지정하면 통일 포맷을 사용할 수 있다. 통일 포맷에서는 첫 두 행에 지정한 파일의 이름과 변경 시각이 표시된다. 3번째 행부터는 차이가 출력되는데 추가된 경우에는 +가, 삭제된 경우에는 -가 표시된다. 통일 포맷에서는 변경된 부분뿐만 아니라 앞뒤 몇 행이 함께 표시된다. 따라서 어디를 수정했는지 파악하기가 쉽다.

@@로 시작되는 행은 다음과 같은 의미를 가진다.

@@-<첫 번째 파일의 변경이 시작된 행>-<변경된 행 수>+<2번째 파일의 변경이 시작된 행>-<변경된 행 수>@@

  1. diff의 사용법과 패치

어떤 파일을 변경한 뒤 다른 사람에게 전달할 때 파일 전체를 전달하는 게 아니라 diff명령어로부터 출력된 부분만 전달하는 것도 가능하다. 변경된 부분을 전달받은 사람은 원래의 파일에 변경된 부분을 적용하여 변경이 완료된 파일을 얻을 수 있다. 그러면 크기가 큰 파일을 변경했을 때 굳이 파일 전체를 전달하지 않아도 된다.

변경된 내용만 담긴 파일을 패치(patch)라고 한다. diff 명령어로 얻은 변경 사항은 patch 명령어로 적용할 수 있다.

패치를 적용할 때 원본 파일이 변경되어 행 번호가 바뀌었다면 에러가 발생할 수 있다. 하지만 통일 포맷을 사용하면 변경 앞뒤의 내용이 포함되어 있어서 어느 정도 변경 사항이 있어도 패치에 성공한다. 따라서 요즘에는 변경 사항을 파악하기 쉽고 패치하기 쉬운 통일 포맷을 많이 사용하고 있다.

통일 포맷은 diff뿐만 아니라 버전 관리 도구인 깃(Git)에서도 사용되고 있다. 따라서 통일 포맷을 통해 차이를 파악하는 것에 익숙해지는 것이 좋다.

profile
WAS Engineer, Cloud Engineer(지망)

0개의 댓글