리눅스 shell을 배워보자 1일차 - 명령어 구조, echo, glob, quote, test, wc, tail, alias

0

linux_shell

목록 보기
1/3

1. 리눅스 shell

실무를 접하기 전에는 언어나 프레임워크에 대한 깊은 이해가 엄청 중요한 줄 알았다. 물론 중요하다. 그러나 리눅스 application 개발을 하면서 느낀 것은 '리눅스 기본 구조나 shell에 대해서 모르면 굉장히 비효율적으로 일할 수 밖에 없구나' 라는 것이었다. 그렇다고 리눅스 shell이 엄청 어렵거나 복잡하진 않다. 알면 쉽다. 그러니 차근차근 공부해나가는 시간을 가져보자.

2. 명령어 구조

리눅스 시스템의 명령어 구조는 다음과 같다.

명령어 -옵션 파라미터

명령어는 시스템에서 제공하는 기본 명령어 일 수도 있고, 사용자가 만든 명령어 일 수도 있다. 옵션은 명령어에 추가적인 기능을 하도록 붙여주는 것인데, 공백 + -가 앞에 붙어야만한다. 파라미터는 해당 명령어나 명령어 옵션에 들어가는 것으로, 이를 기반으로 명령어가 실행된다.

가령 /usr경로의 모든 파일들을 출력해본다고 하자.

ls -l /usr

다음의 명령어를 입력하면

파일 목록들이 쭈욱 나오는 것을 확인할 수 있다.

ls는 파일 목록을 출력하라는 명령어이고, -l은 옵션으로 파일 하나당 하나의 라인으로 출력되었으면 좋겠다는 것이다. /usr은 파라미터로 어떤 경로의 파일 목록을 출력할 지 넣으면 된다.

또한, 옵션은 - 을 하나만 붙이는 경우가 아닌 --와 같이 두개를 붙이는 경우도 있다. 이와 같은 경우는 ---의 경우를 나누는 경우인데, ls -l명령어는 두개를 붙여도 기본 출력 결과와 같다.

ls /usr
ls --l /usr

즉, --l이 따로 뭔가 기능하지 않아서 그렇다. 이후에 -을 두번쓰는 일이 생겨도 놀라지 않으면 된다.

3. echo

printf와 같이 터미널에 문자열을 출력하는 명령어이다.

echo hello world

라고 명령어를 입력하면 hello world가 나온다.

1. 공백문자를 넣고싶은 경우

리눅스 shell에서 공백문자는 단어와 단어, 단어와 옵션 등의 구분자 역할을 한다. 따라서, 여러개의 공백문자는 하나의 구분자로 나타나기 때문에 하나로만 나온다.

echo hello            world

이렇게 쳐도, hello world가 나온다.

그래서 인용 부호인 "" , ''을 사용해주어야 한다.

echo "hello                world"

hello world의 결과가 나온다.

2. e옵션

-e옵션은 특수문자를 화면에 사용할 때 좋다. 즉 제어문자를 사용할 때 좋다.

위에서 인용 부호("", '')를 붙여서 문자를 출력하면 공백이 그대로 나오는 것을 확인할 수 있었다. 그렇다면 특수한 기능을 하는 제어 문자들을 넣으면 그대로 나올까 아니면 printf처럼 그 기능을 하게될까?

echo 'hello           world\n\n\n'

결과는 hello world\n\n\n이다.

이러한 문제를 해결하기 위해서 우리는 ```-e````옵션을 붙여 제어문자를 사용할 수 있도록 한다.

echo -e 'hello           world\n\n\n'

다음과 같이 제대로 나오게 된다.

hello           world



\a와 같이 비프음이 발생하는 기능도 -e옵션을 붙여야 소리가 난다.

특수문자를 사용할 때는 다음과 같은 옵션도 사용이 가능하다.

echo $'\a'

3. n옵션

-n을 붙이면 줄바꿈 처리를 막는다.

echo -n hello world
hello worlduser@...

이렇게 나온다.

4. echo명령어를 이용한 파일 화면 출력

echo *명령어를 이용하면 공백문자 기준으로 현재 path의 파일 목록을 출력해준다.

echo *

다음과 같이 나올 것이다.

file1 file2 file3 ...

ls가 있는데 왜 echo를 사용하는 지 의문일 것이다.

ls는 파일들을 이쁘게 출력해주는 장점이 있지만, substring하기에는 불편한 점이 있다. 반면, echo *은 파일들이 이쁘게 나오지는 않지만, 공백 문자 기준으로 파일들이 열거되기 때문에 이를 이용한 파싱(substring)이 쉽다.

4. glob

glob는 linux 명령어의 특수한 기호로 일반적으로 에스테리스크(*)와 같다. 이는 많은 명령어에 응용될 수 있는데, '모든 파일에 명령어 적용이나 와일드 카드처럼 뒤에 나올 문자열이 아무거나 매칭되면 명령어 적용' 등이 있다.

예를 들어보면

  1. mydir폴더를 만들고 cd mydir로 들어간다.
  2. touch one two three를 통해 파일을 만든다. 참고로 touch명령어는 파라미터에 있는 파일 이름이 현재 경로에 없으면 만들고, 있으면 업데이트 날짜를 현재로 갱신해준다.
  3. (주의)rm *mydir안에 있는 파일을 모두 지워준다. 꼭 자신의 현재 경로가 mydir안에 있다는 것을 확인하고 명령어를 입력하자.
mkdir mydir
cd mydir
touch one two three
rm *

폴더의 모든 파일이 삭제된 것을 확인할 수 있다. rm은 삭제 명령어인데, glob인 *가 붙으면 모두를 의미하므로 모두 삭제된다.

또한, 파일의 내용을 출력하고 싶은데, 파일이 여러개인 경우가 있을 때가 있다.

가령, log파일이 여러개라고 하자.

log_account, log_db, log_auth 이렇게 3개의 로그 파일이 있는데, 이를 한꺼번에 확인하고 싶을 때, glob을 사용하면 쉽고 효율적으로 확인가능하다.

cat 명령어는 파일의 내용을 출력해주는 명령어이다.

cat log_*

이렇게 하면 접두사가 log_를 가진 파일들의 내용들이 모두 출력된다. 즉, glob을 사용하여 이후 이름은 아무거나를 가진 모두를 가져오겠다는 것이다.

5. 인용문

인용문인 "", ''를 적절히 사용하는 것이 굉장히 좋다.

파일을 만드는 touch 명령어를 사용할 때 파라미터 부분이 공백으로 띄어져 있으면 다음과 같은 현상이 발생한다.

파일이름이 hello world wind.mp3인 파일을 만들고 싶다고 하자.

touch hello world wind.mp3
ls

결과는 다음처럼 3개의 파일을 만든다.

hello  wind.mp3  world

왜냐하면 리눅스 명령어는 공백 기준으로 파싱이 이루어지기 때문에 공백이 있다면 잘라내기 때문이다. 따라서, 공백 기준으로 각각이 파일이름이 된 것이다.

이러한 문제를 해결하는 방법이 바로 인용문을 사용하는 것이다.

touch "hello world wind.mp3"
ls

'hello world wind.mp3' 이렇게 출력되었음을 확인할 수 있다.

6. test

명령어를 수행하는데, 특정 조건이 성립이 되어야지만 명령어를 수행하도록 만들고 싶다면 어떻게해야할까?? 그게 바로 test이다.

사용방법이 매우 단순한데, [ ]안에 조건을 써주면 된다.

가장 간단한 예제로, mydir안에 'hello world wind.mp3'가 있다면 mydir안으로 들어가고, 없다면 안들어가겠다. 를 만들어보자.

cd mydir; [ -f 'hello world wind.mp3' ]

mydir안에 hello world wind.mp3파일이 있다면 성공하여 mydir로 path가 바뀌었을 것이다.

하나하나 해제해보면, ;는 '그리고' 라는 의미로, 다음 명령어를 입력하겠다는 것이다. [ ]는 테스트를 의미하는데, 앞선 명령어를 실행하고, 이 조건문을 실행하는데, 실패하면 앞선 명령어들을 모두 rollback하겠다는 것이다.

-f는 파일이 있는 지, 없는 지 확인하는 옵션이고, hello world wind.mp3는 파라미터로 이 파일이 있는 지 없는 지 테스트하는 것이다.

단, 주의할 것은 [과 옵션 -f는 꼭 공백으로 띄워줘야한다. 앞선 다른 예제에도 말했듯이 linux에서 공백은 하나의 구분자이기 때문이다.

7. wc명령어

wc word count 라는 의미로 해당 파일의 단어의 개수와 라인 수, 글자 수들을 출력해준다.

예제를 위해 다음의 파일을 만들어주도록 하자.

echo -e 'grapes\noranges\ntomato\nstrawberry\napple\n' > fruits.txt
cat fruits.txt

다음의 결과가 나온다.

grapes
oranges
tomato
strawberry
apple

이 파일을 wc해보자.

wc fruits.txt

다음의 결과가 나오게 된다.

 6  5 40 fruits.txt

6은 라인의 개수를 의마하고, 5는 단어의 개수, 40은 총 문자의 개수이다. 참고로 개행문자도 포함해서 40이다.

이렇게 wc 명령어를 통해 전반적인 파일의 단어, 문자 개수를 확인할 수 있는데 일부만 알고싶은 경우는 다음과 같이 할 수 있다.

1. wc명령어 옵션

  1. -c: 바이트 개수를 출력한다. 위의 경우 40이 나온다.
  2. -l: newline의 수를 출력한다. 위의 경우 6이다.
  3. -L: 단어 중에 가장 긴 단어의 길이를 출력한다. 10이 된다.
  4. -w: 단어의 개수를 출력한다. 위의 경우 5가 된다.

8. tail

tail은 파일의 후반부, 마지막 쪽부터 출력해주는 명령어이다. -n옵션과 같이 사용하면 파라미터로 몇 개의 라인을 출력할 것인가를 나타낸다. 예시로 확인해보자

seq라는 명령어는 문자를 만들어내는 명령어이다. 파라미터로 시작, 끝값을 주면, 이에 따라 숫자를 생성해낸다.

seq 1 200 > num200
cat num200

참고로 >는 redirection으로 만들어낸 정보를 num200이라는 파일에 넣겠다는 것이다.

결과는 다음과 같다.

1
2
3
...
200

num200파일에 tail이라는 명령어를 주어 마지막 10개를 출력해보도록 하자.

tail -n 10 num200

결과는 다음과 같다.

191
192
193
194
195
196
197
198
199
200

재밌는 것은 -n의 파라미터로 +k라고 해서 +을 붙이면 k부터 끝까지 출력한다.

10
11
12
...
199
200

1. tail의 응용

tail의 정보를 파이프라인(```|````)으로 받아서 처리하는 경우가 많은데 다음과 같다. 가령, 101부터 110까지만 출력하고 싶다고 하자. 그러면 어떻게 해야할까??

tail -n +101 num200 | head -n 10

파이프라인(|)은 왼쪽 명령어의 결과를 오른쪽으로 보내는 역할을 한다. 그리고 오른쪽에서는 해당 결과를 가지고 명령어를 수행하는 것이다. head 명령어는 앞에서부터 10개의 라인을 가져오는 것이다.

결과는 다음과 같다.

101
102
103
104
105
106
107
108
109
110

이렇게 tail과 파이프라인을 이용하여 원하는 부분을 처리하는 경우가 상당히 많다.

또한, -F, -f옵션을 주면 following 기능을 하는데, 이는 해당 파일에 정보가 새롭게 추가되면 이에 따라 현재 출력하는 화면 정보를 업데이트하는 것이다.

sudo tail -f /var/log/syslog

sudo는 관리자 권한을 받기 위함이다. syslog 파일 정보를 읽기 위해서는 관리자 권한을 먼저 받아야한다.

/var/log/syslog는 리눅스 시스템 자체에서 작동하는 정보를 기록하는 로그 파일이다. 이 정보를 tail -f하게되면, 기존 정보를 출력하고, 새로 파일에 추가되는 정보는 실시간으로 화면에 출력되게 된다.

가령, 우리가 현재 컴퓨터에 연결한 USB를 뺏다가 끼면, 새로운 로그가 추가되고 우리 화면에 업데이트될 것이다. 이렇게 tail은 실시간으로 추가되는 정보를 따라가기 좋은 기능을 한다.

9. alias(별칭)

리눅스에서는 명령어를 단축 명령어로 바꿔주는 경우가 있다. 이를 위해 사용하는 명령어가 alias이다.

만약 길고 복잡한 명령어가 있다면 alias로 짧게 만들고, 편리하게 사용할 수 있도록 해줄 수 있다.

이전에 사용했던, sudo tail -f /var/log/syslog라는 명령어를 매번 입력하기 귀찮으니 이 부분을 t로 바꾸어 실행해보자.

alias t='sudo tail -F /var/log/syslog'
t

sudo tail -f /var/log/syslog와 같은 기능을 하게된다. 그런데 만약, /var/log/의 다른 로그를 출력하고 싶다면 어떻게 해야할까?? talias t='sudo tail -F로만 만들고, t /var/log/syslog로 해도될 것이다. 그러나 이렇게 말고,

syslog1, syslog2, syslog3 ... 이있다면 각각
t1, t2, t3로 로그를 불러내고 싶다.

그러나 alias는 파라미터(또는 인자)를 받지 못한다. 즉, 이것은 함수를 사용해야 하는 것이다.

함수 명령어는 function을 써주고, 이름(), 명령어 부분을 써주면 된다.

function tt() { sudo tail -F /var/log/syslog${1};}

파라미터를 받을 때는 ${1}로 써주면 첫번째 인자가 해당 부분에 들어가는 것을 알 수 있다. 다만, ;은 반드시 써주어야 한다.

tt
tt 1
tt 2

로 쓰면 syslog, syslog1, syslog2를 tail하는 것을 확인할 수 있다.

이 처럼 aliasfunction의 가장 큰 차이는 alias는 정말 단축 표현이지, 파라미터를 받을 수 없다는 것이고, function은 단순 단축 표현이 아니므로 파라미터를 받을 수 있다는 것이다.

또한, alias의 가장 큰 단점은 스크립트 파일 내부에서 사용할 수가 없다. 반면, function은 스크립트 파일 내부에서 사용할 수 있다. 무슨 말이냐고 한다면 스크립트 파일 내부에 alias 선언을 한 단축 명령어가 있더라도, 이를 사용할 수가 없다는 것이다.

0개의 댓글