Action disabled: source

리눅스 쉘 스크립트

shell은 작업 환경을 기호화하기 위해서 많은 메카니즘을 제공한다. 앞에서도 언급하였듯이, shell은 단순한 명령어 해석기 이상이며 강력한 프로그래밍 언어이다. shell 스크립트를 작성해 보는 동안 우리는 shell의 향상된 기능을 사용함으로써 유닉스 시스템에서의 작업이 단순화되는 몇 가지 방법을 소개하고자 한다.

위에서도 언급하였듯이, 각각의 shell들은 서로 다른 문법을 사용한다는 것을 shell 스크립트를 실행해봄으로써 확인할 수 있다. 예를 들어, Tcsh는 C와 유사한 문법을 사용하고 Bourne shell은 또 다른 문법의 형태를 사용한다. 이 장에서는 이 두 가지 사이에서 많은 차이점을 고려하여 shell을 작성하지 않고, Bourne shell 문법을 사용하여 실행해 보려 한다.

Shell 스크립트

명령어를 연이어 사용해야 될 경우를 생각해 보자. 단, 그 명령들이 그룹 지어 요구되는 입력 모두를 단 하나의 명령으로 짧게 하려 한다.

  /home/larry# cat chapter1 chapter2 chapter3 > book
  /home/larry# wc -l book
  /home/larry# lp book

파일 chapter1, chapter2, chapter3가 연이어 있고, 그 결과가 파일 book 으로 저장된다. 그러면, book 파일의 총 라인 수가 출력되어지고, 마지막으로 book이 lp명령으로 프린트 될 것이다.

이러한 명령어를 모두 입력하는 대신에, shell 스크립트로 이들을 그룹 지울 수 있다. 이 shell 스크립트는 이러한 명령어의 모두를 실행하기 위해 아래와 같이 만든다.

  %%#%%!/bin/sh
  %%#%% A shell script to create and print the book

cat chapter1 chapter2 chapter3 > book

  wc -l book
  lp book

만일 이 스크립트가 파일 makebook이라는 이름으로 저장되면, 간단히 makebook를 입력할 수 있다.

  /home/larry# makebook

하나의 스크립트 파일로 모든 명령어를 실행한다. shell 스크립트는 보는 바와 같이 단순한 문서 파일이다. emacs나 vi같은 에디터를 사용하여 이것들을 만들 수 있다.

이 shell 스크립트를 보자. 첫 번째 라인 "#!/bin/sh"은 shell 스크립트라는 파일임을 알리며, 스크립트를 실행하는 방법을 말해 준다. 이 명령은 실행을 위하여 shell이 ‘/bin/sh’로 스크립트를 보내는 것이며, ‘/bin/sh’은 shell 그 자신이다. 왜 이것이 중요한가? 대부분의 유닉스 시스템에서는 ‘/bin/sh’ 은 Bash 같은 Bourne shell이다. shell 스크립트를 실행하기위하여 /bin/sh를 사용하는 것이며, 우리는 Bourne shell의 문법으로 스크립트를 실행한다는 것을 확실하게 하는 것이다. 이것은 스크립트가 심지어 사용자가 login 한 Tcsh(C Shell)을 사용한다 할지라도 Bourne 문법을 사용한다는 것을 말해 준다.

두 번째 라인은 주석이다. 주석은 문자 "#"로 시작하며, 그 라인의 끝까지 계속된다. 주석은 shell에 의해 무시되고, 그것은 일반적으로 프로그래머에게 shell 스크립트를 설명하는데 사용된다.

스크립트의 마지막 라인은 명령어이다. 명령어를 shell에게 직접 입력하는 것이다. shell은 스크립트의 각 라인을 읽고 shell 프롬프트에서 입력했었던 것과 같이 실행한다.

사용 허가는 shell 스크립트에서 매우 중요하다. 만일, 사용자가 shell 스크립트를 생성한다면, 그것을 실행하기 위해서 스크립트를 실행 가능한 사용 허가로 확실하게 해야 한다. 작성된 문서파일의 디폴트 사용 허가는 보통 실행 허가를 포함하지 않는다. 따라서, 이 문서파일은 실행 사용 허가를 가져야 한다.

  /home/larry# chmod +x makebook

이 명령은 당신 자신에게 shell 스크립트인 makebook을 실행 가능한 사용 허가로 주는데 사용된다.

Shell 변수와 환경

shell은 대부분의 프로그래밍 언어처럼 변수를 정의할 수 있게 하여 준다. 변수라는 것은 참조할 수 있는 이름이 주어진 데이터이다.

Tcsh나 다른 C형태의 shell들은 여기에서 기술되는 것보다 변수를 설정하는 다른 메카니즘을 사용한다. 여기서는 Bash같은 Bourne shell을 사용하며, Tcsh는 man page 로 상세한 설명을 보기 바란다.

변수의 값을 설정할 때에, "$"라는 변수 이름을 이용하여 변수를 참조할 수 있다.

  /home/larry# foo="hello there"

변수 foo는 "hello there"라는 값이 주어진다. 변수 이름으로 변수의 내용을 지시할 수 있으며 "$" 문자가 앞에 붙는다.

  /home/larry# echo $foo
  hello there
  /home/larry#

같은 결과로 아래와 같이 된다.

  /home/larry# echo "hello there"
  hello there
  /home/larry#

이러한 변수들은 shell 안에 존재하게 된다. 오직 shell을 통해야 만이 이 변수들을 액세스 할 수 있다는 것이다. 이것은 shell 스크립트에 매우 유용하다. 만일 파일 이름을 추적하는 것이 필요하다면, 위에서 설명한 것처럼 그것을 변수로 저장할 수 있다. 명령어 ‘set’을 사용하면 정의된 shell 변수 목록이 출력된다.

어쨌든, shell은 환경을 위한 외부 변수를 사용할 수 있다. 이 환경은 사용자가 액세스하여 실행하려고 하는 모든 명령을 변수로 설정할 수 있다. shell 안에 변수를 정의하면, 그 환경 변수가 필요한 명령어들에게 보내어지며, 명령어에 의해 적절히 사용된다.

아래의 예제에서 환경 변수 PAGER는 ‘man’ 명령어에서 사용되는 것이다. 이것은 man page를 사용할 때에 한 번에 한 화면씩 출력시키는 것이다. 만일 PAGER를 다른 명령어로 설정한다면, man page를 출력하기 위한 명령어로 디폴트인 ‘more’ 대신에 사용될 것이다.

PAGER를 ‘cat’으로 설정하면, ‘man’ 으로부터의 출력은 한 페이지마다 세워지지 않고 한번에 모두 출력될 것이다.

  /home/larry# PAGER="cat"

여기서 환경을 위해 export 명령을 사용해야 한다.

  /home/larry# export PAGER

명령어 ‘man ls’를 해보면, man page는 멈추지 않고 모두 지나가 버릴 것이다.

그럼, PAGER를 ‘more’로 설정하면, ‘more’ 명령어는 man page의 출력으로 사용될 것이다.

  /home/larry# PAGER="more"

PAGER의 값을 변화시킨 후에 ‘export’명령을 사용하면 안된다. 오직 값을 한번만 보내는 것이 필요하며, 변한 값들은 자동적으로 환경으로 전달될 것이다.

특정 명령을 위한 man page는 어떤 환경 변수를 사용하는 명령어가 있을 경우 이 변수를 사용자에게 알려준다. 또한, 어떤 명령어는 환경 변수를 공유한다. 예를 들면, 명령어가 에디터가 필요할 경우 디폴트로 "EDITOR" 환경 변수로 설정된 명령어를 사용한다.

환경은 또한, login 세션에 대한 중요한 정보를 알려주는 데 사용된다. 한 예로 HOME 환경 변수는 홈 디렉토리의 이름을 포함하고 있다.

  /home/larry/papers# echo $HOME
  /home/larry

또 다른 흥미 있는 환경 변수로는 PS1이 있다. 이것은 메인 shell 프롬프트를 정의한다.

  /home/larry# PS1="Your command, please: "
  Your command, please:

일반적인 현재 작업 디렉토리를 표시하는 프롬프트로 되돌아가기 위해서는 아래와 같이 설정하면 된다.

 Your command, please: PS1="\w# "
 /home/larry#

bash의 man page는 프롬프트로 설정하는 데 사용하는 자세한 문법이 설명되어 있다.

PATH 환경 변수

‘ls’명령어를 사용할 때, 어떻게 shell이 ‘ls’ 실행 파일 자체를 찾을 수 있을까? 사실 ‘ls’는 대부분의 시스템에서 /bin 디렉토리 안에 있다. shell은 환경 변수 PATH를 사용하여 사용자가 입력하는 명령들의 실행 파일 위치를 찾는다.

예를 들면, 당신의 PATH는 아래와 같이 설정되어 있을 것이다.

  /bin:/usr/bin:/usr/local/bin:.

이것은 shell이 찾을 수 있는 디렉토리의 목록이며, 각 디렉토리는 “:” 으로 구별되어진다. 사용자가 명령어 ‘ls’를 입력할 때, shell은 먼저 /bin/ls를 찾고, 그리고 /usr/bin/ls 를 찾아가며, 마지막으로 현재 디렉토리를 찾는다.

PATH는 일반 파일을 찾을 때는 아무것도 하지 않는다. 만일 아래와 같이 입력하면,

  /home/larry# cp foo bar

shell은 파일 foo나 bar의 위치를 찾는데 PATH를 사용하지 않는다. shell은 오직 ‘cp’ 실행 파일을 찾는데 PATH를 사용한다.

이것은 사용자에게 많은 시간을 벌어 준다. 이 말은 실행 파일들이 어디에 저장이 되어 있는지 기억을 하지 않아도 된다는 것이다. 많은 시스템에서 실행 파일들은 /usr/bin, /bin, /usr/local/bin 등 여러 장소에 흩어져 있다. 명령의 모든 경로( /usr/bin/cp 같은 )를 입력하는 대신에, 단순히 PATH로 shell이 자동으로 찾아갈 경로들을 설정해 주면 되는 것이다.

PATH가 포함하고 있는 “.” 은 현재 작업 디렉토리이다. 이것은 현재 디렉토리에 있는 실행파일을 명령할때 디렉토리를 포함하여 명령해야하는 부담을 줄여 준다.

Shell 초기화 스크립트

shell 스크립트를 생성하는데 추가적인 설명을 하자면, shell 스크립트는 특정 목적으로 사용되는 경우가 대부분이다. 이런 것들 중에 가장 중요한 것은 초기화 스크립트이며, 이것은 사용자가 login할 때 shell에 의해 자동적으로 실행된다.

초기화 스크립트는 위에서 설명한 것처럼 단순한 shell 스크립트이나, login 할 때 자동으로 실행하는 명령에 의해 환경을 설정하는데 매우 유용하다. 예를 들면, 만일 login 할 때 메일을 언제나 체크하고자 하면 ‘mail’명령을 사용해야 하나, 초기화 shell 스크립트 안에 그 명령을 넣으면 자동으로 실행한다.

Bash 와 Tcsh 모두는 login shell과 또 다른 shell의 요구와 구별된다. login shell은 login 시에 요구되는 shell이며, 보통 이것은 당신이 사용하는 유일한 shell일 것이다. 어쨌든, vi 같은 다른 프로그램이 "shell out"한다면, login shell이 아닌 다른 shell로서 시작해야 한다.

Bash에 의해 사용되는 초기화 파일은 아래와 같은 것이 있다.

/etc/profile 시스템 관리자에 의해 설정되며, login시에 모든 Bash 사용자에게 실행된다.

  $HOME/.bash_profile login Bash 세션에 의해 실행된다. 
  $HOME/.bashrc       Bash로 login 하지 않았을 때 실행된다. 

Tcsh는 다음의 초기화 스크립트를 사용한다.

  /etc/login.csh      login시에 모든 Tcsh 사용자에게 실행된다. 
  $HOME/.tcshrc       login시에 실행된다.
  $HOME/.login        login시에 실행된다.

이 파일들의 기능들을 완전히 이해하기 위해서는 shell에 대하여 많은 지식이 필요하다. shell 프로그래밍은 완전한 한 과목이며, 이 글 전반에 걸쳐 있다. shell 환경을 기호화하려면 bash나 tcsh의 man page를 보는 것이 도움이 될 것이다.