docs/blog/2023-02-06-linux-begin-02.md
2026-08-29 22:09:51 +09:00

341 lines
13 KiB
Markdown

---
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