메뉴
BL
Ars Technica 25일 전

터미널 꾸미기: 당신만의 셸을 공유해 주세요!

IMP
5/10
핵심 요약

이 기사는 그래픽 환경이 보편화된 현대에도 여전히 명령어 기반 터미널 환경이 가진 강력함과 매력을 조명합니다. 저자는 자신의 커리어를 거슬러 올라가며 명령어가 주는 정확한 제어력과 효율성이 어떻게 그를 Windows에서 macOS와 Linux로 이동하게 만들었는지 개인적인 경험을 공유합니다. 나아가 독자들에게 자신이 꾸민 '트릭 아웃(tricked-out)'된 화려한 터미널 환경을 공유해 달라고 요청하고 있습니다.

번역된 본문

텍스트 설정 스토리 텍스트 크기 작게, 표준, 크게 너비 * 표준, 넓게 링크 표준, 오렌지 * 구독자 전용 자세히 보기 탐색창으로 최소화

저는 요즘 터미널 창과 씨름하는 데 예전 그 어느 때보다 많은 시간을 보내고 있습니다. 90년대 초반의 '과거의 저'였다면 이 사실을 결코 믿지 않았을 것입니다. 당시만 해도 불쌍한 MS-DOS는 업계에서 구식이자 멸시의 대상이었고, 적어도 일반 소비자층에서는 Windows(어쩌면 AmigaOS 같은 더 기이한 존재들까지도)와 같은 그래픽 환경이 명령어 인터페이스를 완전히 역사의 뒤안길로 보내고, 우리 모두를 화려한 GUI의 미래로 진입시킬 태세였으니까요.

하지만 결과적으로 명령어는 여전히, 사실 아주 많은 작업에서 최고의 도구로 남아있습니다. 몇 년 전 (아마도 Slashdot에서) 읽었던 현명한 글 중에, 마우스로 클릭하는 인터페이스는 본질적으로 사용자를 화면의 무언가를 가리키며 컴퓨터에게 "해! 그거 해!"라고 우르르거리는 존재로 전락시킨다고 주장하는 것이 있었습니다. (마우스 우클릭 상황에 맞는 메뉴의 등장으로 사용자가 "더 많은 거!"라고 우르르거릴 수 있게 되긴 했지만, 그것이 어휘를 크게 늘려주진 않았습니다.) 이와 대조적으로 명령어는 컴퓨터가 문맥에 따라 해석해야 하는 한두 가지 형태가 아닌, '언어'를 사용하여 사용자가 컴퓨터에게 자신이 원하는 것을 정확하게 지시할 수 있는 기회를 제공합니다.

좀 우스꽝스럽게 들릴지 모르지만, 명령어는 2007년에 제가 Windows를 일상적인 메인 운영체제에서 밀어내는 데 결정적인 역할을 했습니다. 당시 보잉 휴스턴의 당시 최신 EMC Celerra NSX 엔터프라이즈 NAS 어플라이언스 군단을 관리하면서 업무상 정기적으로 bash를 사용해야만 했습니다. GUI 기반의 관리 옵션도 있었지만(혹자에게는 "EMC Control Center"라는 단어가 트라우마를 건드릴지도 모르겠군요), 제가 물려받은 환경은 철저히 bash 스크립트로 엮여 있었습니다.

처음에는 그 모든 Linux적인 것들에 코웃음을 쳤지만, '더 라스트 오브 어스'의 곰팡이처럼 셸의 덩굴이 서서히 제 뇌를 감염시켰습니다. 저는 슬프고도 낡은 cmd.exe와 MS-DOS 배치 파일이 정말 형편없었다는 것을 깨닫기 시작했고, 제 성깔 있는 시스템 관리자 멘토가 하던 Linux식 헛소리가 보이는 것만큼 미친 것이 아니라는 생각이 들었습니다. 그가 직접 컴파일한 Slackware만 구동하겠다는 그의 방식에 도달할 수 있을 거라고는 생각하지 못했고, 실제로 20년이 지난 지금도 여전히 그에 한참 못 미치지만, 그에게도 일리가 있었습니다.

직장에서 유닉스 계열 셸을 많이 사용할수록, 집에서 그것이 더 그리워졌습니다. Windows Vista와 초기 WDDM 문제로 인해 이전에는 SLI로 묶인 두 개의 Nvidia 7900GT 그래픽 카드를 장착한 멋진 메인 PC를 보유했었지만, 결국 끊기고 블루스크린을 뿜어내는 상태로 전락했습니다. Microsoft 운영체제의 미래는 암울해 보였고, Windows 7이 나타나 상황을 바꿔주기까지는 수년이 걸릴 것이었습니다. bash 셸에 대한 노출 요법은 저를 변곡점으로 이끌었고, 결국 저는 Apple 매킨토시 진영으로 뛰어들었습니다. 이는 가능한 모든 세계의 장점을 얻기 위한 계산된 움직임이었습니다. 즉, 훌륭한 그래픽 인터페이스와 직장에서 의존하게 된 것과 동일한 bash 셸을 내부에 갖춘 환경 말입니다.

(전과 후의 모습을 보여주는 사진)

저는 뒤를 돌아본 적이 없습니다. 요즘 저는 집에서 세 가지 다른 운영체제를 사용합니다. MacOS는 여전히 데스크톱의 메인 OS이고, Windows는 구석에 있는 게임용 PC에 설치되어 있으며, Linux(Ubuntu server LTS)는 마땅히 그래야 하듯이 옷장 속에 headless 모드로 돌아가고 있습니다. 신은 하늘에 계시고, 저의 컴퓨팅 세계의 모든 것은 올바르게 돌아가고 있습니다. 그리고 2007년 초 어느 시점 이후 매일 그래왔듯이, 저는 여전히 매일 최소 한두 시간씩 터미널 창을 열고 구식 텍스트 방식으로 작업을 수행합니다.

fish 셸은 오래전 제 맥의 기본 셸이 되었습니다. 이는 제가 fish의 색상을 좋아하고 유용하다고 생각하기 때문이 큽니다(저를 판단하지 마세요!). 하지만 Linux에 로그인했을 때는 여전히 좋은 오래된 bash를 사용합니다. 저는 zsh 및 기타 현대적인 대안들에 그들만의 팬덤이 있다는 것을 알지만, 저는 이미 제 행복한 안식처를 찾았고 거기에 머무는 것에 만족합니다.

원문 보기
원문 보기 (영어)
Text settings Story text Size Small Standard Large Width * Standard Wide Links Standard Orange * Subscribers only Learn more Minimize to nav I spend more time today than ever before interacting with terminal windows, which is something I don’t think Past Me would have believed in the early ’90s. Back then, poor MS-DOS was the staid whipping boy of the industry, and at least on the consumer side, graphical environments like Windows (and maybe even odder creatures like AmigaOS ) seemed poised to stamp the command line into oblivion, leaving text interfaces behind as we all blasted into the ooey-GUI future. As it turns out, though, the command line is still the best tool for some jobs—many jobs, in fact. I read a wise post some years ago (probably on Slashdot) arguing that a mouse-driven point-and-click interface essentially reduces the user to pointing at something on the screen and grunting, “DO! DO THAT!” at the computer. (The rise of right-click context menus adds the ability for the user to also grunt “MORE THINGS!” but doesn’t otherwise add vocabulary.) The command line, by contrast, gives the user the opportunity to precisely tell the computer what they want done, using words instead of one or two gestalts that the computer must interpret based on context. It sounds kind of silly to say it, but the command line is what finally dragged me off Windows as my daily driver back in 2007. At the time, I’d been forced into regular bash usage at work as I took over the day-to-day administration of Boeing Houston’s fleet of then-brand-new EMC Celerra NSX enterprise NAS appliances , and while there were GUI management options available (I am perhaps triggering trauma in a small subset of older readers by saying the words “EMC Control Center”), the environment I’d inherited was firmly held together by bash scripts. At first, I had turned up my nose at the Linux-ness of it all, but kind of like the fungus in The Last of Us , the shell’s tendrils slowly infected my brain. I began to realize that sad old cmd.exe and MS-DOS batch files really were kind of terrible, and that maybe, just maybe , the Linux-y ravings of my angry graybeard sysadmin mentor were not as crazy as they seemed. I didn’t think I’d ever arrive at his method of only running manually compiled Slackware —and, indeed, 20 years on, I’m still not even close—but the guy had a point. The more I used a Unix-y shell at work, the more I began to miss it at home. Windows Vista and its early WDDM woes had reduced my previously badass main PC with two Nvidia 7900GT cards in SLI to a stuttering BSOD-spitting mess, and the future of Microsoft OSes looked bleak—Windows 7 wouldn’t be along to change the situation for years. Exposure therapy to the bash shell brought me to the tipping point, and I jumped ship to the Macintosh side of the house. It was a move calculated to give me the best of all possible worlds—a good graphical interface with the same bash shell under the hood that I’d come to depend on at work. The before… Lee Hutchinson The before… Lee Hutchinson …and the after. Lee Hutchinson …and the after. Lee Hutchinson The before… Lee Hutchinson …and the after. Lee Hutchinson I haven’t looked back. These days, I run three different operating systems at home. MacOS is still my daily driver on the desktop; Windows lives on the gaming PC in the corner; and Linux (in the form of Ubuntu server LTS) is headless in the closet, where it belongs. God is in his heaven, and all is right with my computing world—and still, as with every day since sometime in early 2007, I spend at least an hour or two with a terminal window doing things the old-fashioned, text-y way. The fish shell long ago became my default on my Mac, in no small part because I like fish’s colors and find them helpful (don’t judge me!). When I’m logged into Linux, though, I stick with good old bash. I know zsh and other modern alternatives have their fans, but I’ve found my happy place, and I’m content to stay there. Being a child of the BBS era , when ANSI graphics were the hotness, I have spent about as much time as any other terminal-enjoying admin customizing my environment and making it into a place where I feel comfy working. … Oh God, I’m doing it. I’m doing the thing they do on recipe sites where all the reader really wants is directions for making pecan pie but instead gets a giant personal backstory. Forgive me. I’m old. Let’s get to the pie, and by pie, I mean the screenshots and code! My favorite thing: The terminal timer It’s incredibly handy, at least for me, to have an easy-to-see reference of how long the last command took to run. (You don’t need that kind of thing until you need it, and then you often really need it.) To that end, I have some functions living in my .bashrc file that time each command and then append that time—and the last error code emitted—to the next bash prompt. In practice, it looks like this: I dig this. Coupled with printing the current time as part of the prompt, it gives you a good idea of not just how long the last few commands took to run but also when you were running them. That’s very handy for absentminded admins (/me raises hand) who leave terminal sessions up for days at a time with important work sitting in them. Here’s the code to make this happen, which you should feel free to adapt to your needs. As noted, I keep this in .bashrc as part of my PS1 prompt statement: color_prompt=yes if [ "$color_prompt" = yes ]; then _TIMER_FILE="/tmp/.bash_timer_${$}" function _timer_record_start { date +%s%N > "$_TIMER_FILE" } function timer_stop { if [[ ! -f "$_TIMER_FILE" ]]; then timer_show=0us return fi local timer_start timer_start=$(< "$_TIMER_FILE") rm -f "$_TIMER_FILE" local delta_us=$((($(date +%s%N) - timer_start) / 1000)) local us=$((delta_us % 1000)) local ms=$(((delta_us / 1000) % 1000)) local s=$(((delta_us / 1000000) % 60)) local m=$(((delta_us / 60000000) % 60)) local h=$((delta_us / 3600000000)) # Goal: always show around 3 digits of accuracy if ((h > 0)); then timer_show=${h}h${m}m elif ((m > 0)); then timer_show=${m}m${s}s elif ((s >= 10)); then timer_show=${s}.$((ms / 100))s elif ((s > 0)); then timer_show=${s}.$(printf %03d $ms)s elif ((ms >= 100)); then timer_show=${ms}ms elif ((ms > 0)); then timer_show=${ms}.$((us / 100))ms else timer_show=${us}us fi } PS0='$(_timer_record_start)' #Prompt and prompt colors function set_prompt { local Last_Command=${1:-$?} FancyX='\342\234\227' Checkmark='\342\234\223' export PS1="\n$WHITE[\t] " if [[ $Last_Command == 0 ]]; then PS1+="\$? $GREEN$Checkmark " else PS1+="\$? $RED$FancyX " fi timer_stop PS1+="$WHITE($timer_show)" PS1+="\n\[$HOSTCOLOR\]\u@\h\[$WHITE\]:\[$BLUEBOLD\]\w\[$WHITE\] \\$ " } function timer_prompt_command { local last_command=$? set_prompt "$last_command" } PROMPT_COMMAND='timer_prompt_command' fi This mess of functions will jam all that goodness into your prompt, complete with a fancy green “check” if the program exited with error code 0 or a red “X” and the error code if it exited with something else. The color definitions— $WHITE , $BLUEBOLD , $HOSTCOLOR , and others—are just plain ol’ ANSI escape sequences defined elsewhere in .bashrc and not presented here to try to keep the code excerpts from being too long. You can and should replace them with whatever tickles your fancy. The timer_stop function also has the job of converting the timer into a human-readable format, and it’s probably messier than it needs to be. I’m no developer, though, so this is what Past Lee settled on after a few hours of searching through examples. Doing it in fish for folks like me That’s for bash when I’m ssh’d into one of my Linux hosts, but I run fish on MacOS. I have a separate fish function for getting the same results there, complete with gross hacks for turning the measurement into human-readable form. I made this code, and I am unapologetic. Witness my cobbled-together StackOverflow-sourced kludge. function fish_prompt --description 'Write out the