--- title: "리눅스 입문 part 2" description: "1장에 이어서 명령어, 이론, 요령을 알아본다." image: "/assets/blog/02-linux-begin-02/Standard-unix-filesystem-hierarchy.svg" authors: [bitdori] --- ### 권한 ![ln-s3](/assets/blog/01-cygwin/ln-s3.png) ls에 `-l` 옵션을 붙여서 파일 목록을 출력하면 여러 가지 정보가 나오는데 소유자명, 시각, 파일명 및 링크 [포인터][포인터]로 구성돼 있다는 건 대충 알아볼 수 있으나 첫 번째로 나오는 `-rw-r--r--` 와 같은 문자는 어떤 뜻인지 알아보지 못 할 수도 있다. 이는 [Symbolic notation][Symbolic notation]라고 불리는 읽기/쓰기/실행 권한 표기문자 이다. 총 10글자로 돼 있는데, 맨 왼쪽 한 개를 뺀 아홉 개는 3개씩 끊어서 각각 소유자(u)/그룹(g)/기타(o)의 권한을 표시한다. `-rw-r--r--` 인 경우 - 소유자: 읽기/쓰기 (read/write) - 해당 파일이 지정된 그룹: 읽기만 (read) - 소유자도 파일의 그룹도 아닌 기타 사용자: 읽기만 (read) 할 수 있는 상태인 것이다. 예를 하나 더 들어 `lrwxrwxrwx` 인 경우 파일소유자/그룹/기타 모두 모든 권한을 보유하고 있는 것이다. (read/write/execute) 맨 왼쪽 `l` 은 _Symbolic link_ 임을 알려주고 있는데, 다른 [표현형][표현형]으로는 - `-`: 일반 정규 파일 - `d`: 디렉토리 - `p`: [기명 파이프][기명 파이프] - `s`: [소켓][소켓] - `c`: Character device - `b`: Block device 가 있다. - `cd ~/opt/cygwin-test` - `ls -l` ![file-type-directory](/assets/blog/02-linux-begin-02/file-type-directory.png) Symbolic notation의 r/w/x/- 문자는 각각 4/2/1/0 이 대입되는 [8진수][8진수]로 이루어져 있다. 따라서 예로 들고 있는 `-rw-r--r--` 은 _644_ 권한이 들어가 있는 것이다. 같은 방식으로 `lrwxrwxrwx` 는 _777_ 권한으로 치환할 수 있다. ### 유틸리티 part 2 `cat /var/log/setup.log` 로 Cygwin 설치 중 기록된 메세지를 확인할 수 있었는데, 내용이 길어서 head와 tail로 끊어보았다. - `less /var/log/setup.log` 실행 ![less](/assets/blog/02-linux-begin-02/less.png) head/tail은 한 번만 출력하고 끝내는 명령인데, `less` 는 `man`과 마찬가지로 `f` / `b` 키를 누르면서 계속 본문을 탐색할 수 있다. - `q` 를 눌러서 less 종료 `less` 커맨드가 개발되기 전에 `more` 라는 명령어가 먼저 나왔는데 less가 기능이 더 좋지만 [more][more]는 도스에서도 기본 탑재하던 커맨드이기 때문에 less를 쓸 수 없는 아주 제한적인 환경에서는 more를 less 대신 사용할 수도 있을 것이다. --- - `cat /var/log/setup.log | wc -l` 실행 ![wc](/assets/blog/02-linux-begin-02/wc.png) 어떤 숫자가 출력됐는데 setup.log 속 내용이 몇 줄이나 들어있는지 [wc][wc]에 `-l` 옵션을 줘서 계산한 것이다. cat과 wc 사이를 [파이프라인][파이프라인]으로 이어줬는데 서로 다른 프로그램이 마치 한 개로 합쳐진 것처럼 명령을 수행한다. &&는 따로따로 실행하는 명령을 표기만 한 줄로 엮을 때 사용하기 때문에 위 명령을 `cat /var/log/setup.log && wc -l` 로 실행하면 예상과는 다른 결과가 나올 것이다. ![and](/assets/blog/02-linux-begin-02/and.png) - [`Ctrl c`][`Ctrl c`] 를 눌러서 종료 ### [Shell script][Shell script] 다음과 같은 명령을 실행한다고 해 보자 - `mkdir -p ~/opt/cygwin-test && touch testfile && echo "line1" >> testfile && cp testfile testfile2 && cat testfile2 && ls -l` 특별할 것 없는 명령이긴하나 1. 같은 커맨드를 또 다시 입력하고 싶지 않을 때 2. 내용을 깔끔하게 작성하고 싶을 때 3. 외우고 싶지 않을 때 세울 수 있는 대안책으로 shell script를 작성할 수 있다. `vi test-script.sh` 를 실행해서 해당 내용을 입력한다. ```sh #!/usr/bin/env bash mkdir -p ~/opt/cygwin-test touch testfile echo "line1" >> testfile cp testfile testfile2 cat testfile2 ls - l ``` ![shell-script-1](/assets/blog/02-linux-begin-02/shell-script-1.png) ![shell-script-2](/assets/blog/02-linux-begin-02/shell-script-2.png) - `ls -l` - `chmod +x test-script.sh` - `ls -l` ![shell-script-3](/assets/blog/02-linux-begin-02/shell-script-3.png) - `./test-s` 까지만 입력하고 [`Tab`][`Tab`] 키를 눌러서 나머지 자동완성 - Enter를 눌러서 실행 ![shell-script-execute](/assets/blog/02-linux-begin-02/shell-script-execute.png) 위에서 입력한 명령을 연쇄적으로 실행하였다. FHS에서 `..` 으로 dot을 두 개 입력하면 상위 디렉토리를 가리키고, _`.` 한 개만 입력하면 현재 디렉토리_ 를 가리킨다. 즉 `./test-script.sh` 라고 입력한 부분은 현재 위치(pwd)에 있는 test-script.sh 파일을 실행하겠다는 뜻이 된다. - `chmod -x test-script.sh` - `./test-script.sh` ![permission-denied](/assets/blog/02-linux-begin-02/permission-denied.png) 실행을 거부하고 있다. [chmod][chmod] 는 rwx 권한을 변경할 때 사용한다. 맨 처음 shell script를 저장하고 곧바로 `chmod +x` 라는 것을 실행했는데 `x` 권한을 덧붙여서 실행할 수 있는 상태로 만들었던 것이다. 이후 `-x` 를 하여 다시 실행권한이 없어졌기 때문에 _Permission denied_ 를 출력하면서 실행을 거부했다. `./test-s` 까지만 입력하고 탭 키를 눌렀을 때 나머지 `./test-script.sh` 까지 [자동완성][자동완성]이 됐는데, "" 사이에 문자열을 입력할 때 처럼 자동완성을 할 수 없는 경우가 있지만 대부분 경우에는 지원을 해 주고 있다. chmod -x 로 실행권한이 빠졌을 때 자동완성이 되지 않았을텐데 이러한 동작으로 [실행 가능 파일][실행 가능 파일]인지 아닌지 짐작해 볼 수 있다. 스크립트 첫 줄에 입력한 `#!/usr/bin/env bash` 라인은 hashbang 또는 [shebang][shebang] 이라는 부분이며 _이 스크립트를 어떻게 실행할 것인가_ 결정하는 부분이다. ![env](/assets/blog/02-linux-begin-02/env.png) `ls /usr/bin` 을 해 보면 `env` 라는 프로그램이 있는데 이 프로그램으로 bash가 있는 위치를 탐색하도록 조치한 것이다. [애플 맥OS에서는 zsh][zsh for mac] 을 기본 인터프리터로 설정해 놓았기 때문에 `#!/usr/bin/env zsh` 로 작성하게 될 것이다. [`/usr/bin/env`][env] 가 없거나 이를 사용하지 않는 경우 어떤 스크립트에는 `#!/bin/sh` 가 입력되어 있는 경우도 있는데 /bin/sh는 [POSIX sh][POSIX sh]이며 bash나 zsh이 아니기 때문에 동작방식이 다를 수도 있다. ### 파일 탐색 `/usr/bin` 에 `env` 가 있다는 사실은 해당 문서를 통해서 또는 경험적으로 알게된 것이지만 경험해 본 적 없는 새로운 파일, 새로운 커맨드가 있는 위치를 찾아보는 명령어로 [`which`][`which`] 와 [`whereis`][`whereis`] 가 있다. ![command search](/assets/blog/02-linux-begin-02/command-search.png) `which env` 와 `whereis env` 로 env의 위치를 탐색해보면 둘 다 env 위치를 출력하긴 하지만 which는 출력값이 단 하나인 것에 비해 whereis는 다른 값도 보여주고 있다. - `which 찾는대상`: 실행가능파일(executable)이 있는 위치 출력 - `whereis 찾는대상`: [이진 파일][이진 파일], 소스, 매뉴얼이 있는 위치 출력 근데, which와 whereis는 커맨드를 어디에서 찾아야 할지 어떻게 알고 있는 걸까? 이들을 실행하면 [PATH][PATH]라는 [환경 변수][환경 변수]로부터 경로값을 읽고 명령을 수행한다. `echo $PATH` 를 실행하면 _PATH_ 에 어떤 값이 들어있는지 볼 수 있는데, 여기에서 _/usr/bin_ 을 볼 수 있다. 커맨드의 위치를 찾아주는 which / whereis와 달리 [`find`][`find`]로는 특정 파일을 어떤 경로 내에서 찾을 수 있다. - `cd /opt/cygwin-test` - `ls` - `find . -name "test*"` _test_ 로 시작하는 파일 내역을 현재 위치에서부터 하위 디렉토리 내부까지 탐색했다. ![find](/assets/blog/02-linux-begin-02/find.png) ### bash 활용 다음과 같은 명령을 실행하려고 한다. `mkdir`_-p_ `~/opt/cygwin-test/subdir && cd $_ && touch newfile && echo "line1" >> newfile && ls && cat newfile` 전체 커맨드의 앞 단계에서 띄어쓰기를 빼먹어서 에러를 발생시킬 것이다. 커서를 앞 부분으로 하나씩 하나씩 옮겨서 띄어쓰기를 넣고 다시 실행하면 정상적으로 진행이 되겠지만 [Readline][Readline] 단축키로 커서를 더 빠르게 이동시킬 수 있다. - 잘못된 커맨드 우선 실행 - 윗 화살표로 커맨드 다시 표시 - `Ctrl a` 로 커서 맨 앞으로 이동 후 잘못된 부분 수정 위/아래 화살표로 이전 커맨드를 찾는 대신 전체 내역을 보고 싶어질 수 있는데 [`history`][`history`] 커맨드로 예전 기록을 확인할 수 있다. ![history-1](/assets/blog/02-linux-begin-02/history-1.png) history가 출력되면 원하는 내용을 복사 후 붙여넣기해서 Readline 단축키로 수정하려는 부분을 바꾸면 된다. - `Ctrl e`: 커서를 맨 뒤로 이동 (end) - `Alt b`: 커서를 한 단어 왼쪽으로 이동 (backward) - `Alt f`: 커서를 한 단어 오른쪽으로 이동 (forward) Readline 단축키는 [`info`][`info`]와 [emacs][emacs]에서도 활용하고 있다. 이미 실행했던 커맨드가 많아서 하나하나 찾기 힘든 경우 `history | grep -i 검색어` 형식으로 [`grep`][`grep`]을 이용해서 찾아낼 수도 있다. grep의 `-i` 옵션은 대소문자에 상관 없이 같은 알파벳이면 결과를 보여주도록 하는 옵션이다 (case insensitive) ![hist-grep](/assets/blog/02-linux-begin-02/hist-grep.png) ## Cygwin 환경설정 Cygwin은 [mintty][mintty]라는 터미널 위에서 돌아가는데, 이 mintty 설정을 통해서 폰트 등을 변경할 수 있다. https://fonts.google.com/download?family=Noto%20Sans%20Mono 에서 Noto Mono 계열 폰트를 받은 뒤 압축을 해제하면 `NotoSansMono-VariableFont_wdth,wght` 와 static 폴더가 있는데 VariableFont는 모든 폰트를 한 번에 설치하지만 용량이 그만큼 크다. static에서는 필요한 폰트를 하나씩 설치하도록 되어 있다. ![noto](/assets/blog/02-linux-begin-02/noto.png) Cygwin 우클릭 - Options... ![cygwin-context-menu](/assets/blog/02-linux-begin-02/cygwin-context-menu.png) Text 항목에서 Font를 Select... ![cygwin-font-select](/assets/blog/02-linux-begin-02/cygwin-font-select.png) Font Size도 좀 더 크게 바꾸어 보았다. ![cygwin-font-applied](/assets/blog/02-linux-begin-02/cygwin-font-applied.png) https://fonts.google.com/specimen/Roboto+Mono https://github.com/naver/d2codingfont/releases https://github.com/be5invis/Sarasa-Gothic/releases {/* Options - Text - Font: Noto Mono Font smoothing: default .minttyrc FontChoice=CJK:5;Hangul:9 Font5=Sarasa Fixed K Font9=Sarasa Fixed K Emojis=noto CursorType=block CursorBlinks=no Font=Noto Mono Locale=C Charset=UTF-8 FontSmoothing=default FontHeight=12 Scrollbar=none Language=en_US BoldAsColour=no BoldAsFont=no Transparency=off OpaqueWhenFocused=yes Term=xterm-256color */} [포인터]: https://en.wikipedia.org/wiki/Pointer_(computer_programming) "Pointer" [Symbolic notation]: https://en.wikipedia.org/wiki/File-system_permissions#Symbolic_notation [표현형]: https://en.wikipedia.org/wiki/Unix_file_types "Representations" [기명 파이프]: https://en.wikipedia.org/wiki/Named_pipe "Named pipe" [소켓]: https://en.wikipedia.org/wiki/Unix_domain_socket "socket" [8진수]: https://en.wikipedia.org/wiki/Octal [more]: https://en.wikipedia.org/wiki/More_(command) [wc]: https://en.wikipedia.org/wiki/Wc_(Unix) "Word Count" [`Ctrl c`]: https://en.wikipedia.org/wiki/Signal_(IPC)#SIGINT "Signal Interrupt" [Shell script]: https://en.wikipedia.org/wiki/Shell_script [파이프라인]: https://en.wikipedia.org/wiki/Pipeline_(Unix) "Pipeline" [`Tab`]: https://en.wikipedia.org/wiki/Tab_key "탭 키" [chmod]: https://en.wikipedia.org/wiki/Chmod "change mode" [자동완성]: https://en.wikipedia.org/wiki/Command-line_completion "completion" [실행 가능 파일]: https://en.wikipedia.org/wiki/Executable "Executable" [shebang]: https://en.wikipedia.org/wiki/Shebang_(Unix) [zsh for mac]: https://support.apple.com/en-us/HT208050 [env]: https://en.wikipedia.org/wiki/Env "env" [POSIX sh]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html "sh" [`which`]: https://carlowood.github.io/which/ "GNU which" [`whereis`]: https://en.wikipedia.org/wiki/Whereis [이진 파일]: https://en.wikipedia.org/wiki/Binary_file "Binary file" [PATH]: https://en.wikipedia.org/wiki/PATH_(variable) [환경 변수]: https://en.wikipedia.org/wiki/Environment_variable "Environment variable" [`find`]: https://en.wikipedia.org/wiki/Find_(Unix) [Readline]: https://en.wikipedia.org/wiki/GNU_Readline "GNU Readline" [`history`]: https://en.wikipedia.org/wiki/History_(command) [`info`]: https://en.wikipedia.org/wiki/Info_(Unix) [emacs]: https://en.wikipedia.org/wiki/Emacs "이맥스" [`grep`]: https://en.wikipedia.org/wiki/Grep "g/re/p" [mintty]: https://github.com/mintty/mintty/wiki/Tips#secondary-fonts