셸 언어의 한계
셸 언어는 대화형(interactive) 작업에 매우 유용합니다. 하지만 이러한 최적화는 프로그래밍 언어로서의 활용성과 상충되는 경우가 많아, 실제로 셸 스크립트를 작성하다 보면 그 한계를 자주 느끼게 됩니다.
그렇다면 여러분의 셸이 더 확장성 있는 프로그래밍 언어까지 이해할 수 있다면 어떨까요? 예를 들어, 파이썬(Python)처럼요?
그 해답이 바로 Xonsh입니다.
Xonsh 설치와 첫 만남
Xonsh 설치는 생각보다 간단합니다. 가상 환경을 하나 생성한 뒤, pip install xonsh[ptk,linux] 명령으로 패키지를 설치하고, xonsh를 실행하기만 하면 됩니다.
처음 실행하면 파이썬 셸치고는 다소 낯선 프롬프트가 보여 의아할 수 있습니다:
$ 1+1
2
일단 훌륭한 계산기부터 되는군요!
$ print("hello world")
hello world
물론 다른 함수도 호출할 수 있습니다:
$ from antigravity import geohash
$ geohash(37.421542, -122.085589, b'2005-05-26-10458.68')
37.857713 -122.544543
셸과 파이썬의 자연스러운 결합
흥미로운 점은, Xonsh를 일반 셸처럼 사용할 수도 있다는 사실입니다:
$ echo "hello world"
hello world
심지어 두 방식을 자유롭게 섞어 쓸 수도 있습니다!
$ for i in range(3):
. echo "hello world"
.
hello world
hello world
hello world
강력한 자동 완성
Xonsh는 Prompt Toolkit을 활용하여 셸 명령어와 파이썬 표현식 모두에 대해 자동 완성을 지원합니다. 자동 완성 기능은 시각적으로도 정보가 풍부해서, 입력 가능한 후보들을 보여주고 화면 안(in-band) 드롭다운 목록으로 손쉽게 선택할 수 있게 해줍니다.
환경 변수 접근
환경 변수 접근 역시 지원합니다. Xonsh는 환경 변수에 파이썬 타입을 적용하기 위해 단순하지만 강력한 휴리스틱을 사용합니다. 기본 타입은 "문자열(string)"이지만, 예컨대 경로(path) 변수는 자동으로 리스트로 처리됩니다.
$ '/usr/bin' in $PATH
True
불리언 단축 연산자
Xonsh는 셸 스타일과 파이썬 스타일의 불리언 단축 연산자를 모두 받아들입니다:
$ cat things
foo
$ grep -q foo things and echo "found"
found
$ grep -q bar things && echo "found"
$ grep -q foo things or echo "found"
$ grep -q bar things || echo "found"
found
즉, 파이썬 키워드는 별도로 해석된다는 뜻입니다. 유명한 닥터 수스(Dr. Seuss) 동화책의 제목을 출력하려면 키워드 부분을 따옴표로 감싸 주어야 합니다.
$ echo green eggs "and" ham
green eggs and ham
따옴표로 감싸지 않으면 뜻밖의 결과를 마주하게 됩니다:
$ echo green eggs and ham
green eggs
xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
xonsh: subprocess mode: command not found: ham
Did you mean one of the following?
as: Command (/usr/bin/as)
ht: Command (/usr/bin/ht)
mag: Command (/usr/bin/mag)
ar: Command (/usr/bin/ar)
nm: Command (/usr/bin/nm)
가상 환경 관리, vox
가상 환경을 다루는 부분은 조금 까다로울 수 있습니다. 일반적인 가상 환경 도구는 Bash와 비슷한 문법에 의존하기 때문에 Xonsh에서는 작동하지 않습니다. 대신 Xonsh는 vox라는 자체 가상 환경 관리 시스템을 함께 제공합니다.
vox는 ~/.virtualenvs 디렉터리 안에서 가상 환경을 생성하고, 활성화 및 비활성화할 수 있습니다. virtualenvwrapper를 사용해 본 경험이 있다면 익숙한 위치일 겁니다.
다만 주의할 점이 있습니다. 현재 활성화된 가상 환경은 xonsh 자체에는 영향을 주지 않습니다. 즉, 활성화된 환경에 설치된 모듈을 xonsh에서 import할 수는 없습니다.
$ xontrib load vox
$ vox create my-environment
...
$ vox activate my-environment
Activated "my-environment".
$ pip install money
...
$ python
...
>>> import money
>>> money.Money('3.14')
$ import money
xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
ModuleNotFoundError: No module named 'money'
xontrib: Xonsh의 확장 생태계
위 예제의 첫 번째 줄은 vox를 활성화하는 명령입니다. vox는 xontrib, 즉 Xonsh용 서드파티 확장입니다. xontrib 관리자를 통해 사용 가능한 모든 xontrib 목록과 각각의 현재 상태(설치됨, 로드됨, 아니면 둘 다 아님)를 확인할 수 있습니다.
직접 xontrib를 개발한 뒤 PyPI에 업로드만 해서 공개할 수도 있습니다. 하지만 xontrib 색인(index)에 등록해 두면 Xonsh가 미리 해당 확장을 인식할 수 있어 좋은 관행으로 여겨집니다. 덕분에 예를 들어 설정 마법사(configuration wizard)가 사용자에게 해당 확장을 추천할 수도 있습니다.
마무리
"파이썬을 내 셸로 쓸 수 있을까?"라고 한 번이라도 궁금해 본 적이 있다면, pip install xonsh 한 줄이면 바로 그 답을 확인할 수 있습니다.