독자는 무슨 차를 운전하든지 간에 개조한 자동차의 진가를 인정해야 한다. 다섯 개의 살로 된 마그네슘 합금 바퀴, 광폭 타이어, 미드나잇 블랙 색상으로 마감되고 풍성하게 크롬 처리된 빅 블럭 엔진 소리가 요란한 1969년형 Dodge Charger만한 것은 거의 없다. 그것은 작품이다 — 자동차 로댕의 생각하는 사람이 운전할 것이다. 고전이다.
UNIX® 쉘 역시 고전이다(대형 펜더는 없음). 하지만 약간의 고된 노동과 조작 시간 및 개조를 통해 이 또한 개조된 자동차처럼 보이고 작동할 수 있다. 이를 "최상위 기어헤드(Top Gear-head)" 또는 "엄청난 쉘 변신(Extreme Shell Makeover)"이라고 할 수 있다. 필자는 이를 멋지다고 생각한다!
깜박이는 프롬프트 아래 쉘— Bash, Z 쉘 또는 기타 등등이어야 함 —은 늘리고 성능 조정하고 수정할 수 있는 움직이는 부품이 많다. 요약하면 다음과 같다(이러한 많은 내용들이 이전 컬럼에서 자세히 논의된 대로).
- 별명은 명령어와 명령행 구를 축약할 수 있다. 예를 들어,
alias ll 'ls -hlt'를 작성하면 일반적으로 사용되는 명령행을 겨우 두 개의 문자로 줄인다 —입력하는 내용과 기억하는 내용이 줄어든다. 거의 대부분의 경우에 별명은 리터럴을 축약한다. 하지만, 쉘 스크립트 또는 쉘 함수와 매우 비슷하게 별명은 매개변수로 승인될 수도 있다. 명령alias print 'lpr -h -Pps5 \!*'는\!*를 명령행 인수로 바꾼다. 그러므로print manual.ps schematic.ps form.ps를 입력하면lpr -h -Pps5 manual.ps schematic.ps form.ps로 확장된다. - 환경 변수는 명령들 사이에, 심지어 새 프로세스를 낳는 명령들 사이에도 설정을 지속한다. 일부 환경 변수는 관례적인 이유로 특수 의미를 가진다. 즉, 명령과 애플리케이션은 PRINTER를 독자가 선호하는 출력 장치로서 인식하는 반면, EDITOR와 PAGER는 텍스트를 각각 수정하고 표시하기 위해 어느 텍스트 편집기와 뷰어를 사용하는지 표시한다. 다른 환경 변수는 개별 유틸리티와 밀접한 관련이 있다. 한 예제는 PS1이다. 이는 쉘에 초기 프롬프트에 렌더링하는 것을 알려준다. 또 다른 주요한 작업 환경 변수는 쉘의 PATH이며, 이는 실행 파일을 검색하는 디렉토리를 열거한다. (어느 환경 변수가 특정 애플리케이션이나 명령에서 인식되는지 알아보려면 man 페이지의 "환경 변수"라는 섹션을 찾아보자.)
- 함수는 명령행으로도 호출 가능하며, 별명과 완전한 스크립트 사이에 간격을 채운다. 예를 들어, 인수를 조작하거나 논리를 적용해야 하는 경우 별명이 충분하지 않을 수 있지만, 전체 스크립트가 과잉일 수 있다. 함수는 또한 누적된 효과를 달성하기 위해 결합될 수도 있다. 함수를 작성하는 약간의 프로그래밍 요령이 있어야 하지만, 힘들지는 않다.
- 쉘 옵션은 쉘의 작동을 제어한다. 쉘 옵션은 대개 쉘마다 다르고
Bash 또는 Z 쉘과 같은 서식있는 쉘은 성능 조정 가능한 매개변수를 많이 가질 수 있다. (Z 쉘은
구성 가능성을 문서화하기 위해서만 zshoptions이라는 전용 man 페이지가 있다.) 예를 들어, Z 쉘 옵션
pushd_ignore_dups를 사용하는 경우,pushd는 디렉토리가 이미 존재하는 경우 디렉토리를 해당 디렉토리 스택으로 밀어넣지 않을 것이다. 옵션을 탐색하는 데 그야말로 수많은 시간을 낭비할 수 있다. 한 번 유지하려는 조합을 찾으면,set(Bash) 또는setopt를 입력하고 출력을 파일로 경로 재지정한다. 쉘을 열 때마다 작업공간을 재작성하기 위해 캡처한 설정의 일부 또는 전부를 시작 파일로 복사할 수 있다.
이러한 기어와 레버 이외에도 쉘의 모습을 변경할 수 있다.
특징이 없는 달러 부호($) 프롬프트는 색상을 선보이고 현재 작업 중인 디렉토리를
반영하며 심지어 날씨를 표시할 수도 있다. 명령으로 약간의 정보를 캡처할 수 있는 경우, 아마도 이러한 데이터를
해당 프롬프트에 표시할 수 있다.
쉘에서 다른 작업과 마찬가지로, 환경 변수는 쉘이 프롬프트를 표시할 때마다 그리는 것을 제어한다. 변수 PS1 또는 "prompt string level 1"은 명령행 자체와 같이 렌더링 될 때 해석된다. PS1은 기타 쉘 및 환경 변수, 위치내(in-place) 명령 평가(역따옴표 사용) 및 특수 리터럴을 포함할 수 있다. 초기 예제는 다음과 같다.
$ export PS1="\u@\h \w >" strike@nostromo ~ > whoami; hostname; pwd strike nostromo /home/strike strike@nostromo ~ > |
처음에 해당 프롬프트는 간단한 $이다. 환경 변수
PS1(따라서, set이 아니라
export)을 \u@\h \w >로 설정하면
독자의 사용자 이름(\u의 의미), 리터럴
@, 호스트 이름(\h),
현재 작업 중인 디렉토리 (\w) 및 리터럴 문자열
>를 렌더링한다.
다른 특수 리터럴은 시간에 대해 \t(24시간 형식으로)
날짜에 대해 \d(요일, 월, 일 형식으로) 그리고 쉘 히스토리 번호에 대해
\!를 포함한다. 연장된 기간 동안 쉘 창을 열린 상태로 유지하는 경우,
이전 명령을 !nnn로 신속하게 반복할 수 있으며, 여기에서
nnn은 명령에 대해 프롬프트에 표시되는 숫자이다.
strike@nostromo ~ > export PS1="\! $ " 776 $ find . -name ... ... 999 $ !776 find . -name ... 1000 $ |
수퍼유저, 루트이거나 그와 같이 동작할 때마다 쉘 프롬프트가 번호 기호(#)로
어떻게 변경하는지 궁금하게 생각한 적이 있는가?
기본값으로 표준 프롬프트는 실제로 특수 연산자
\$이다. 독자의 효율적인 사용자 ID가 0인 경우, 이는
#을 내보낸다. 그렇지 않으면 이는 $를 내보낸다.
약어도 색상을 변경하기 위해 존재한다. 시연하는 또 다른 샘플은 다음과 같다.
strike@nostromo ~ > export PS1='$ ' $ blue='\e[0;34m' $ none='\e[m' $ export PS1="$blue\u@\h$none\w>" <span style="color: blue;">strike@nostromo </span>~ ><br /> |
(다소 통제하기 힘든) 약어인 \e[0;34m은 파란색을 사용한다. 보완물인 \e[m은
쉘 창에 대해 렌더링 색상을 기본값으로 다시 설정한다. 두 코드 다 하나의 작은따옴표로 둘러싸여
쉘에 특수 의미를 가지는 문자가 삽입되는 것을 방지한다.
이 예제는 또한 프롬프트에서 변수를 사용할 수 있음도 표시한다. 여기에서 변수
blue 및 none은
명령행이 해석될 때 확장되고, 해당 프롬프트는 확장의 결과로 나타나는 문자열로 설정된다. 프롬프트가
렌더링될 때마다 변수를 동적으로 확장하려는 경우, 해석이 설정될 때 이스케이프(escape)해야 한다. 바로 다음을 살펴보자.
<span style="color: blue;">strike@nostromo
</span>~ >export PS1="\$somevar $ "
$ somevar="hello"
hello $
|
\$somevar 절은 달러 부호를 이스케이프하여, 프롬프트가 설정되는 명령에서 변수의
해석을 방지한다. 대신에, 해석은 프롬프트가 그려질 때마다 나타난다. somevar가
다른 명령으로 인해 변경하면, 프롬프트는 새 값을 표시한다.
이전에 언급한 대로 프롬프트에서 어느 명령 또는 함수나 호출할 수 있다.
역따옴표(``)를 사용하기만 하면 된다. 예를 들어, Ruby 언어 버전과
해석기 사이에 전환하기 위해 Ruby Version Manager를 사용하는 경우, 어느 Ruby 바이너리가 활성인지
알려고 할 수 있다. 다음 두 가지 접근방식이 존재한다.
hello $ export PS1="(`which ruby`) \w $ " (/Users/strike/.rvm/rubies/ruby-1.9.2-p0/bin/ruby) ~ $ |
첫 번째 기술은 which를 적용하여 현재 PATH에서 첫 번째 Ruby 실행 파일을
찾는다. 이 다음 기술은 동일한 목표를 완수하지만, 위치내 명령 평가가 얼마나 복잡할 수 있는지 시연한다. 프롬프트를 문자열로 설정한 경우
다음과 같다.
"(`rvm info | grep 'ruby:' | grep bin | cut -f2 -d: | tr \\" ' '`)" |
비록 더 돌아가는 경로를 사용하더라도 동일한 결과를 얻는다.
한편, PS1이 "prompt string level 1"인 이유를 궁금한 적이 있을 수 있다. 다른 프롬프트 레벨이 있는가? 응답은 예이다. 환경 변수는 PS2, PS3 및 PS4에 대해 존재하고, 이러한 프롬프트는 새 블록을 열 때마다 표시된다. 다음과 같이 한 번 출현한다.
$ for i in [A-Z]* > |
for i in [A-Z]*를 입력하고 리턴(Return)을 누른 후에 쉘은
현재 for 루프의 본문 내에 있는 것을 강조하기 위해 PS2
프롬프트(기본값은 >임)를 표시한다. 다시 말해서, 이제 루프 또는
다음 심화 레벨에서 "중첩"되었다. 루프를 done으로 완료하는 경우 첫 번째 레벨
프롬프트가 다시 나타난다.
$ for i in [A-Z]* > do > echo $i > done Gemfile Gemfile.lock README Rakefile $ |
실제로 이전 프롬프트에서 명령행을 완료하지 않는 아무때나 새 프롬프트가 표시된다. 이는 일치하지 않는 작은 따옴포나 큰 따옴표 표시로 인해 새 프롬프트가 왜 표시되는 지를 설명한다. 쉘은 프롬프트로 독자가 시작한 것을 계속하도록 표시하고 있다(말장난을 의도하는 것이 아님).
프롬프트에 정보를 임베드하는 것은 현재 호스트, 작업 중인 디렉토리 및 기타 등등의 상태를 추적하는 훌륭한 방법이다. 원하는 프롬프트를 작성하면, 쉘 시작 파일을 사용자의 모든 계정에 분배한다. 대부분의 현대 사용자와 마찬가지로 독자의 화면을 원격 쉘 창으로 채우는 경우, 프롬프트는 따로 분리하는 데 도움을 줄 수 있다. 프롬프트를 각 호스트에서 다른 색상으로 변경하는 함수를 제작할 수 있다.
쉘을 사용자 정의하는 것은 영원한 괴짜의 오락거리이고, 자체적인 작업을 찾기 위해 엄청난 양의 영감과 소스 코드 온라인을 찾을 수 있다. 두 개의 소스인 Oh My Z Shell! 및 Bash It!은 특별히 언급할 가치가 있다. 전자는 Z 쉘 사용자를 위한 것이고, 후자는 Bash 애호가를 위한 것이다. 두 가지 모두는 완성, 테마(색상 및 프롬프트), 함수 및 미리 준비된 "점" 파일을 포함하여 쉘 수정의 콜렉션이다. 둘 다 오픈 소스이고 github에서 다운로드 할 수 있다. 여기에서 Oh, My Z Shell!(또는 약어로 OMZ!)을 시도해보자. 코드를 사용하려면 Z 쉘 버전 4.3.9 이상을 보유해야 한다.
패키지를 설치하고 목록 1과 같이 쉘을 wget를 통해
Z 쉘로 자동으로 변경할 수 있다.
목록 1. Z 쉘로 설치 및 변경
$ wget http://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh
...
Cloning Oh My Zsh...
Cloning into /Users/strike/.oh-my-zsh...
remote: Counting objects: 1312, done.
remote: Compressing objects: 100% (750/750), done.
remote: Total 1312 (delta 796), reused 944 (delta 520)
Receiving objects: 100% (1312/1312), 153.63 KiB, done.
Resolving deltas: 100% (796/796), done.
Looking for an existing zsh config...
Using the Oh My Zsh template file and adding it to ~/.zshrc
Copying your current PATH and adding it to the end of ~/.zshrc for you.
Time to change your default shell to zsh!
Changing shell for strike.
Password for strike:
chsh: /usr/bin/env zsh: non-standard shell
__ __
____ / /_ ____ ___ __ __ ____ _____/ /_
/ __ \/ __ \ / __ `__ \/ / / / /_ / / ___/ __ \
/ /_/ / / / / / / / / / / /_/ / / /_(__ ) / / /
\____/_/ /_/ /_/ /_/ /_/\__, / /___/____/_/ /_/
/____/
|
선택적으로 키트를 수동으로 설치할 수 있다. 그렇게 하는 것은 또 다른 쉘을 실행 중이고 Z 쉘을 시도하려는
경우 더 나을 것이다. Git를 사용하여 패키지를 복제한 다음에
다음과 같이 zsh를 실행한다.
$ git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh $ cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc $ zsh |
그림 1과 유사한 화면과 프롬프트가 표시되어야 한다.
OMZ!에 대한 기본값은 "robbyrussell"이라 하고, OMZ!의 스튜어드(steward)를 따라 시조가 되는 이름이
지정되었다. 이를 ~/.oh-my-zsh/themes에 나열된 어느 테마이든지 그 중 하나로 변경할 수 있다. 테마를 변경하려면
~/.zshrc 파일을 열고 ZSH_THEME 변수를 테마 파일의 기본 이름으로 설정한다. 예를 들어,
cloud.zsh-theme을 사용하려면 ZSH_THEME=cloud를 설정한다.
그림 1. 쉘의 테마 변경하기
많은 테마의 인쇄 상태 정보는 프롬프트에 나와 있고
프롬프트의 맨 오른쪽에 나와 있음을 확인할 가능성이 높다. 예를 들어, Clean 테마는 맨 오른쪽에서
현재 시간을 인쇄한다. 화면 에뮬레이터는 대개 맨 아래 상태 표시줄을 포함하지 않지만(해당 하드웨어 창시자와는
다름) 동적 피드백을 위해 프롬프트의 맨 오른쪽에 표시된 부동산을 사용할 수 있다. 프롬프트에서
색상을 설정하는 우스운 \e[ 코드를 기억하는가? 창 주변 커서를 이동하는 이러한
광범위한 "이스케이프" 세트가 있다. 게다가 비밀 기호와 숫자를 사용하는 것이 아니라
현대식 UNIX 시스템은 tput를 사용하여 이름 또는 용도별로 이스케이프를 찾고
내보낸다. Z 쉘은 이러한 모든 속임수를 사용하여 처음과 이어지는 행에서 각각 오른쪽 프롬프트에 대해 RPS1
및 RPS2를 제공한다.
색상 및 프롬프트의 테마식 처리를 넘어서 OMZ!는 함수와 기능과 같이 그룹화하는 플러그인을 포함한다. 예를 들어,
소스 제어에 대해 Git를 사용하는 경우 Git OMZ! 플러그인을 사용하여 Git 상태로 프롬프트를 수정할 수
있다. 다시 한 번 더 ~/.zshrc 파일을 열고 플러그인 행을 편집하여
git>를 포함한다. 이제 독자가 Git 환매 부동산으로 전환할 때, 프롬프트는 상태를
반영한다. 예를 들어, 그림 2는 아직 단계화되지 않은 수정을 통해 Clean 테마와 저장소를 표시한다.
그림 2. Clean 테마 및 저장소
영리하게도 프롬프트는 현재 브랜치("rubricmods") 및 빨간색 X를 표시하여, 현재 저장소가 더티(dirty)이거나
로컬 파일이 수정되었지만 커미트되지 않았음을 보여준다. 변경사항이 커미트되면, X가 삭제된다. 또한 Git
플러그인도 일반적인 Git 명령 조합에 유용한 별명과 Git 옵션에 컨텍스트 인식을 추가한다. 이렇게 시도해보자.
git branch에 이어 Tab 키를 입력하면, Git 플러그인이 사용 가능한 브랜치를
나열한다. 다른 플러그인은 Mac OS X, Ruby on Rails 개발, MySQL 및 기타 등등에 대해 존재한다. 일부
플러그인은 경미하지만, 아마도 한 두 가지의 함수 또는 어떤 별명에 지나지 않는다. 즉, 다른 플러그인은
더 광범위하다.
Dirpersist는 OMZ! 플러그인의 의도를 보여주는 좋은 전시물이다. Dirpersist는 쉘 호출에 걸쳐 디렉토리 스택을 저장하고 복원하므로, 중요한 상태를 보존하기 때문에 작업을 중단한 지점에서 재개할 수 있다. 이를 사용하려면 플러그인을 ~/.zshrc로 추가한다. 플러그인의 소스는 간단하고 목록 2에 나와 있다.
목록 2. OMZ! 플러그인 소스
#!/bin/zsh
#
# Make the dirstack more persistent
#
# Add dirpersist to $plugins in ~/.zshrc to load
#
# $zdirstore is the file used to persist the stack
zdirstore=~/.zdirstore
dirpersistinstall () {
if grep 'dirpersiststore' ~/.zlogout > /dev/null; then
else
if read -q \?"Would you like to set up your .zlogout file for
use with dirpersist? (y/n) "; then
echo "# Store dirs stack\n\
# See ~/.oh-my-zsh/plugins/dirspersist.plugin.zsh\ndirpersiststore" >> ~/.zlogout
else
echo "If you don't want this message to appear, remove dirspersist from \$plugins"
fi
fi
}
dirpersiststore () {
dirs -p | perl -e 'foreach (reverse <STDIN>) {\
chomp;s/([& ])/\\$1/g ;print "if [ -d $_ ]; then pushd -q $_; fi\n"}' > $zdirstore
}
dirpersistrestore () {
if [ -f $zdirstore ]; then
source $zdirstore
fi
}
DIRSTACKSIZE=10
setopt autopushd pushdminus pushdsilent pushdtohome pushdignoredups
dirpersistinstall
dirpersistrestore
# Make popd changes permanent without having to wait for logout
alias popd="popd;dirpersiststore"
|
플러그인은 세 가지 함수, 편리한 쉘 옵션과 각 팝 조작으로 디렉토리 스택을 지속하는
popd에 대한 별명으로 구성된다. 플러그인도 환경을 초기화하여,
디렉토리 스택을 저장하는 장소를 작성하고 Z 쉘 로그아웃 파일인 ~/.zlogout을 수정하여,
로그아웃할 때마다 디렉토리 스택을 지속한다. 확인 가능한 대로 새 플러그인은 작성하기에 간편하고
어느 쉘 명령 세트이든지 이와 관련하여 하나를 빌드할 수 있다.
독자가 OMZ!를 선호하지만 Bash 쉘을 사용하는 경우 Bash It!을 시도해보자. 이는 OMZ!에서 영감을 받았고 유사한 조작이 있다. Bash It은 또한 Subversion 및 nginx에 대한 플러그인을 제공한다.
OMZ! 또는 Bash It!의 후드를 열어 쉘 사용자 정의를 째깍거리게 만드는 것을 살펴보자. "점 파일" 절을 웹에서 검색하여 지혜와 진기함을 찾을 수도 있다. 즉, 많은 UNIX 기어헤드들은 다른 사람들이 골라 모으도록 개인용 쉘 구성을 온라인에 게시한다. 여기 팁도 있다. 즉, 버전 제어의 일부 형식으로 점 파일을 유지하자. 저장소가 주어지면 변경과 다른 쉘을 실험하는 데 더 편안하게 느낄 가능성이 높다. 실수를 하거나 특정 쉘 또는 시나리오에 대해 변형을 유지하는 경우 이전 버전으로 되돌릴 수 있다. 쉘은 유연하고 동적이며, 하나의 크기 필요가 모두에 맞지는 않다. 훌륭한 "점 파일" 세트가 있으면 다른 사람과 공유하자. 점 파일을 과시한다고 다음 "분노의 질주(The Fast and the Furious)"에서 주연 역할을 따낼 수는 없지만, 독자의 괴짜 성향은 급격히 신장될 가능성이 높다.
교육
-
Z shell: Z 쉘의 소스와 해당 쉘의 프로젝트 페이지에서 광범위한 문서와 튜토리얼을
찾을 수 있다.
-
Bash 문서:
Bash 쉘과 터미널 커서 및 렌더링 옵션에 대해 자세히 읽어보자.
-
Oh My Z Shell!: 오픈 소스 프로젝트를 확인하여
확장과 Z 쉘로의 유용한 바로 가기를 추가하자.
-
Bash It!: 이 커뮤니티 프로젝트는 Bash 쉘에 확장의 프레임워크와 편리성을
제공한다.
-
많은 개발자들과 오픈 소스 프로젝트는 코드를
Git 및 github로 버전 제어 하에 유지한다.
-
Speaking UNIX: 본 시리즈의 다른 파트를 살펴본다.
-
AIX와 UNIX developerWorks 영역: AIX와 UNIX 영역에서는 AIX 시스템 관리와 UNIX 스킬 확장의 모든 측면과 관련된 풍부한 정보를 제공한다.
-
AIX와 UNIX 입문
AIX와 UNIX 입문 페이지에서 자세한 정보를 볼 수 있다.
-
기술 서점: 다양한 기술 주제와 관련된 서적을 살펴볼 수 있다.
제품 및 기술 얻기
-
Bash 쉘: GNU Software Foundation에서 Bash 쉘의 소스를
다운로드하자.
토론
-
developerWorks 블로그: 블로그를
읽어 보고 developerWorks community에 참여하자.
-
다음과 같은 AIX 및 UNIX 포럼에 참여하자.
- AIX 5L—기술 포럼
- 개발자용 AIX 포럼
- Cluster Systems Management
- IBM Support Assistant
- Performance Tools—기술적
- 기타 AIX 및 UNIX 포럼
