본문 바로가기
프로그래밍 놀이터/Script(Python)

[책 정리] 05. 쉘을 이해하기 - 리눅스 커맨드라인 쉘 스크립트 바이블

by 돼지왕 왕돼지 2020. 4. 24.
반응형

쉘의 유형 알아보기


-

시스템이 실행시키는 쉘 프로그램은 사용자 ID 구성에 따라 달라진다.

/etc/passwd 파일 안에는 사용자 ID 마다 일곱 번째 필드에 어떤 기본 쉘 프로그램을 실행시킬 것인지가 나와 있다.

기본 쉘 프로그램은 사용자가 가상 콘솔 터미널에 로그인하거나 GUI 터미널 에뮬레이터를 시작할 때마다 실행된다.


기본인 bash 쉘은 물론 CentOS 의 tcsh, 데비안의 dash 등도 있다.

그러나 bash 쉘이 인기가 좋아 다른 쉘을 기본 쉘로 사용하는 사람들이 그리 많지는 않다.



-

기본 시스템 쉘은 또 다른 쉘인 /bin/sh 이다.

시스템 시동과 같은 때에 필요한 시스템 쉘 스크립트에 기본 시스템 쉘이 사용된다.

/bin/sh 이 bash 를 소프트링크(심볼릭 링크) 하는 경우도 있다.




부모와 자식 쉘의 관계 알아보기


-

/bin/bash 명령 또는 그와 같은 효과를 내는 bash 명령이 CLI 프롬프트에 입력되면 새로운 쉘 프로그램이 실행된다.

이는 자식 쉘(서브쉘)이다.

자식 쉘 프로세스가 실행될 때에는 부모 쉘 환경의 일부만이 자식 쉘 환경으로 복사된다.

이는 변수와 같은 부분에서 문제를 일으킬 수 있으며, 이는 추후에 다룬다.



* 프로세스 목록 알아보기


-

순차적으로 실행될 명령의 목록을 한 줄에 지정할 수 있다

명령 사이에 세미콜론(;)을 사용하여 명령 목록을 입력하면 된다.

$ pwd; ls; cd /etc; pwd; cd; pwd; ls


명령 목록이 프로세스 목록으로 간주되려면 명령들을 괄호로 둘러싸야 한다.

$ (pwd; ls; cd /etc; pwd; cd; pwd; ls)


별 차이가 없어 보이지만, 이 차이는 매우 다른 영향을 준다.

괄호를 더해서 명령목록을 프로세스 목록으로 바꾸면 명령은 서브쉘에서 실행된다.

괄호 안에 또 다른 괄호를 두어 서브쉘의 서브쉘을 또 만들 수도 있다.



-

환경변수를 보려면 아래와 같이 한다.

$ echo $환경변수

$ echo $BASH_SUBSHELL

BASH_SUBSHELL 환경변수는 서브쉘이 있으면 1, 없으면 0 값을 준다.



-

서브쉘은 쉘 스크립트에서 멀티프로세싱을 위해 사용되지만 서브쉘을 쓰면 비싼 대가를 치러야 한다.

처리를 상당히 느리게 만들기 때문이다.

그리고 이는 진정한 멀티프로세싱이 아니다.

터미널이 서브쉘의 입출력에 발이 묶이기 때문이다.



* 서브쉘을 창의적으로 사용하기


-

서브쉘을 사용하는 더욱 생산적인 방법이 있다.

프로세스 목록, 코프로세스 및 파이프는 서브쉘을 사용한다.

대화형 쉘 안에서 이를 모두 효율적으로 사용할 수 있다.


대화형 쉘에서 서브쉘을 사용하는 생산적 방법 가운데 하나는 백그라운드 모드를 활용하는 것이다.



** 백그라운드 모드 들여다보기


-

백그라운드 모드에서 명령을 실행하면 명령이 처리되는 동안에도 CLI 는 자유롭게 다른 일을 할 수 있다.

백그라운드 모드로 돌리고 싶다면 마지막에 & 문자를 붙인다.

$ sleep 10 &

백그라운드 모드로 들어갈 때는 백그라운드 작업의 번호와 PID 가 출력된다.



-

ps 명령 말고도 백그라운드 작업 정보를 표시하기 위해서 jobs 명령을 사용할 수 있다.

jobs 명령은 현재 백그라운드 모드에서 실행되고 있는 프로세스를     출력한다.

-l 옵션을 주면 더욱 많은 정보를 볼 수 있다.


백그라운드 작업이 완료되면 그 완료 상태가 표시된다.

이는 적절한 시기를 감안해서 표시되는 것이 아니기 때문에 갑자기 표시될 수 있음에 놀라지 말자.



** 프로세스 목록을 백그라운드 모드로 돌리기


-

$ (sleep 2; echo $BASH_SHELL; sleep 2)&



** 코프로세싱 살펴보기


-

코프로세싱(co-processing)은 두 가지 작업을 동시에 수행하는 것을 말한다.

백그라운드 모드에서 서브쉘을 생성하고 서브쉘에서 명령을 실행한다.

코프로세싱을 실행하려면 서브쉘에서 실행해야 할 명령과 함께 coproc 명령을 사용한다.

$ coproc sleep 10

코프로세싱은 서브쉘을 생성한다는 사실을 제외하면 백그라운드 모드에서 명령을 돌리는 것과 거의 똑같이 동작한다.


$ jobs

[1]+ Running    coproc COPROC sleep 10 &


여기서 COPROC 은 coproc 명령이 프로세스에 부여한 이름이다.

명령에 대한 확장 구문을 사용하여 이름을 직접 설정할 수도 있다.

$ coproc My_Job { sleep 10; }

여기서 주의할 것은 "중괄호와 실행시킬 명령 사이에 빈칸이 반드시 하나" 있어야 한다. 그리고 "명령은 반드시 세미콜론(;)으로 끝나야" 한다. 마지막으로 "세미콜론과 중괄호 사이에도 빈 칸이 반드시 하나 있어야 한다.



-

코프로세싱은 대단히 높은 차원의 기능을 제공하며 서브쉘에서 실행되는프로세스와 정보를 주고받을 수 있다.

코프로세스에 이름이 필요한 유일한 경우는 여러 코프로세스가 실행되고 있으며 이들이 서로 통신할 필요가 있을 때 뿐이다.

그렇지 않으면 그냥 coproc 명령만 사용해도 충분하다.



-

서브쉘을 생성하려면 많은 자원이 투입되고 느려질 수 있다는 점을 반드시 기억하자.




내장 쉘 명령 알아보기


* 외부 명령 살펴보기


-

파일시스템 명령이라고도 하는 외부 명령은 bash 쉘의 외부에 존재하는 프로그램이다.

이들 명령은 쉘 프로그램에 내장되어 있지 않다.

외부 명령은 보통 /bin, /usr/bin, /sbin 또는 /usr/sbin 에 있다.

$ which ps # ps 명령의 파일 이름을 찾을 수 있다.

$ type -a ps

외부 명령이 실행될 때마다 자식 프로세스가 생성된다.

이러한 동작을 포크(fork)라고 한다.

프로세스가 포크를 해야 할 때마다 자식 프로세스의 환경을 설정하려면 시간과 자원이 들어가 외부 명령은 자원 소모가 약간 많을 수 있다.

내장 명령을 사용할 때에는 포크가 필요 없어서 자원 소모가 적다.



-

자식 프로세스 또는 서브쉘을 포크했다면 신호를 통해서 이들과 통신할 수 있다

이는 커맨드라인에서나 쉘 스크립트를 만들 때에나 굉장히 유용하다

프로세스들은 신호를 통해서 통신할 수 있다.




내장 명령 살펴보기


-

내장 명령들은 자식 프로세스를 실행시킬 필요가 없다는 점에서 외부 명령과 다르다.

이들은 쉘과 함께 컴파일되므로 쉘의 여러 기능 가운데 일부를 이루고 있다.


cd, exit 명령은 모두 bash 쉘에 내장되어 있다.

type 명령을 사용해서 어떤 령이 내장 명령인지 여부를 확인할 수 있다.



-

몇몇 명령은 여러 가지 특성이 있다.

예를 들어 echo 와 pwd 명령은 내장 명령의 특성만이 아니라 외부 명령의 특성도 있다.

type 명령에 -a 옵션을 사용하면 명령의 여러 가지 특성을 볼 수 있다.

참고로 which 명령은 외부 명령 파일만을 보여 준다.



** history 명령 사용하기


-

쓸모 있는 내장 명령 가운데 history 명령이 있다.

bash 쉘은 사용했던 명령을 기억한다.

history 명령을 활용하면 사용했던 명령을 기억하고 다시 사용할 수 있다.

보통 history 는 최근에 썼던 1000개 명령을 보관한다.

(bash history 가 보관하는 명령의 수를 지정하려면 HISTSIZE 라는 환경 변수를 바꾸면 된다.)



-

마지막 명령을 불러들이고 재사용하려면 !! 를 입력하면 된다.



-

명령 히스토리는 사용자의 홈 디렉토리에 있으며 보이지 않는 .bash_history 파일에 보관한다.

bash 명령 히스토리는 메모리에 저장된 다음 쉘에서 나갈 때 기록 파일에 저장한다.

만약 쉘에서 나갈 때가 아닌 평소에 항상 history 파일에 기록하길 원한다면 -a 옵션을 주면 된다.

$ history -a



-

여러 터미널 세션이 열려있어 열린 각 세션마다 history -a 명령을 사용하여 .bash_history 파일에 히스토리를 추가할 수 있다.

그러나 열려있는 다른 터미널 세션의 히스토리가 자동으로 업데이트 되지는 않는다.

.bash_history 파일은 터미널 세션이 처음으로 시작되었을 때 읽기 전용이 되기 때문이다.

.bash_history 파일을 다시 읽어들이고 세션의 히스토리를 업데이트하도록 강제하려면 -n 명령을 사용한다.

$ history -n



-

느낌표와 함께 history 의 번호를 부르면 해당 명령을 바로 불러올 수 있다.

$ !20



** 명령의 별명 사용하기


-

쉘 내장 명령 중 alias 가 있다.

alias 명령으로 자주 쓰는 명령의 별명을 만들 수 있다.


사용할 수 있는 별명의 목록을 보려면 alias 명령에 -p 옵션을 주면 된다.

$ alias -p


나만의 alias 를 만들려면 다음과 같이 하면 된다.

$ alias li = 'ls -li'



-

명령의 별명은 내장 명령이기 때문에 그 명령이 정의되어 있는 쉘 프로세스에 대해서만 유효하다.

다행히 별명을 영속화시켜 서브쉘에서 쓸 수 있도록 만들 수 있다.

이는 환경변수에 선언하면 되는데 나중에 다룬다.




반응형

댓글