์ด ๋ฌธ์๋ Bash๋ฅผ ๋ฐฐ์ฐ๊ณ ์ถ์ ์ฌ๋์ ์ํด ์์ฑ๋์์ง๋ง ๊น์ ๋ด์ฉ์ ๋ค๋ฃจ์ง๋ ์์ต๋๋ค.
Tip: learnyoubash - ์ด ํธ๋๋ถ ๋ด์ฉ์ ๋ํด์ interactiveํ ์ํฌ์์ ์งํํ ์ ์์ต๋๋ค.
npm
์ ์ด์ฉํด์ ์ด ํธ๋๋ถ์ ์ค์นํ ์ ์์ต๋๋ค. ๋ค์ ๋ช
๋ น์ด๋ฅผ ์คํํ์ญ์์ค:
$ npm install -g bash-handbook
์ค์น ํ bash-handbook
๋ช
๋ น์ ์คํํฉ๋๋ค. $PAGER
์ ํ์๋ฅผ ์ด์ฉํ์ฌ ๋งค๋ด์ผ ํ์ด์ง๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ์๋๋ฉด ๊ณ์ ์ฌ๊ธฐ์ ์ฝ์ผ์
๋ ๋ฉ๋๋ค.
์์ค ์ฝ๋๋ ์ฌ๊ธฐ์ ์์ต๋๋ค: https://github.com/denysdovhan/bash-handbook
- Introduction
- Shells and modes
- Comments
- Variables
- Shell expansions
- Arrays
- Streams, pipes and lists
- Conditional statements
- Loops
- Functions
- Debugging
- Afterword
- Other resources
- License
๋น์ ์ด ๊ฐ๋ฐ์๋ผ๋ฉด ์๊ฐ์ด ์ผ๋ง๋ ๊ฐ์น์๋ ์์์ธ์ง ์๊ณ ์์ ๊ฒ์ ๋๋ค. ์ ๋ฌด ํ๋ก์ธ์ค๋ฅผ ์ต์ ํํ๋ ๊ฒ์ ์ผ์ ์งํํ๋๋ฐ ์์ด์ ๊ฐ์ฅ ์ค์ํ ์ธก๋ฉด ์ค ํ๋์ ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ๋ช ๋ฒ์ด๊ณ ๋ฐ๋ณตํด์ผํ๋ ์์ ์์๋ ํจ์จ์ฑ๊ณผ ์์ฐ์ฑ์ ๋์ด๊ธฐ ์ํ ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค:
- ์๋ฒ์์ ์คํฌ๋ฆฐ์ท์ ์ฐ๊ฑฐ๋ ์ ๋ก๋ฉํ๋ ๊ฒฝ์ฐ
- ๋ง์ ํ ์คํธ๋ค์ ๋ณด๊ธฐ ์ข๊ฒ ๋ง๋ค๊ฑฐ๋ ์์์ ๋ง์ถ๋ ๊ฒฝ์ฐ
- ํ์ผ์ ๋ค๋ฅธ ํฌ๋งท์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ
- ํ๋ก๊ทธ๋จ์์ ๋์ค๋ ์ถ๋ ฅ์ ๊ตฌ๋ฌธํด์ํ๋ ๊ฒฝ์ฐ
์ด๋ฐ ์์ ์์๋ Bash๊ฐ ๋ฐ๋ก ์ฐ๋ฆฌ์ ๊ตฌ์ธ์ฃผ์ ๋๋ค!
Bash๋ Bourne shell์ ๋์ฒดํ GNU ํ๋ก์ ํธ๋ก [Brain Fox][]์ํด ์์ฑ๋ Unix ์ ธ์ ๋๋ค. 1989๋ ์ ๋ฐฐํฌ๋์์ผ๋ฉฐ, Linux์ macOS์์ ๊ธฐ๋ณธ ์ ธ๋ก ์ค๋ซ๋์ ์ฌ์ฉ๋์์ต๋๋ค.
๊ทธ๋ผ ์ฐ๋ฆฌ๋ ์ 30๋ ๋ ๋ ๋ ๊ธฐ์ ์ ๋ฐฐ์์ผ ๋ ๊น์? ๋๋ต์ ๊ฐ๋จํฉ๋๋ค: ์ด _something_์ ์ค๋๋ ๋ชจ๋ Unix ๊ธฐ๋ฐ ์์คํ ์์ ํจ์จ์ ์ธ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๊ธฐ ์ํ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๋๊ตฌ ์ค ํ๋์ด๋ฉฐ, ์ด๊ฒ์ด ๋น์ ์ด Bash๋ฅผ ๋ฐฐ์์ผ ํ๋ ์ด์ ์ ๋๋ค. ์ด์.
์ด ํธ๋๋ถ์ bash์์ ์ฌ์ฉํ๋ ๊ฐ์ฅ ์ค์ํ ๊ฐ๋ ์ ์ค๋ช ํ๊ณ ์์ต๋๋ค. ๋ ์ด ์์ฝํ ๊ฒ์ด ๋น์ ์๊ฒ ๋์์ด ๋์์ผ๋ฉด ํฉ๋๋ค.
Bash ์ ธ์ interactive ๋ชจ๋์ non-interactive ๋ชจ๋, ๋๊ฐ์ง ๋ชจ๋๋ก ์์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
๋น์ ์ด Ubuntu์์ ์์
์ ํ๊ณ ์๋ค๋ฉด, 7๊ฐ๋ ๋๋ ๊ฐ์ ํฐ๋ฏธ๋์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฐ์คํฌํฑ ํ๊ฒฝ์์ 7๋ฒ์งธ ๊ฐ์ ํฐ๋ฏธ๋์ธ GUI ๋ชจ๋๋ก ๋์์ค๊ณ ์ถ๋ค๋ฉด Ctrl-Alt-F7
์ ์ด์ฉํ์ฌ GUI๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Ctrl-Alt-F1
ํค๋ฅผ ์ด์ฉํ์ฌ ์
ธ์ ์ด ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์น์ํ GUI๋ ์ฌ๋ผ์ง๊ณ 1๋ฒ ๊ฐ์ ํฐ๋ฏธ๋์ด ๋ณด์
๋๋ค.
Interactive ๋ชจ๋์์ ์์ ์ค์ด๋ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ ๋๋ค:
user@host:~$
์ฌ๊ธฐ์ ์ฌ๋ฌ ๊ฐ์ง Unix ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ ์ ์์ต๋๋ค. ls
, grep
, cd
, mkdir
, rm
๊ณผ ๊ฐ์ ๋ช
๋ น์ ์คํํ๊ณ ๊ฒฐ๊ณผ๊ฐ์ ํ์ธํ ์ ์์ต๋๋ค.
์ ธ์ด ์ฌ์ฉ์์ ์ง์ ์ํธ ์์ฉ์ ํ๊ธฐ์ ์ฐ๋ฆฌ๋ ์ ธ๊ณผ interactive๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
๊ฐ์ ํฐ๋ฏธ๋ ์ฌ์ฉ์ ๋ถํธํฉ๋๋ค. ์๋ก, ํ ๋ฒ์ ๋ฌธ์๋ฅผ ์์ ํ๊ณ , ๋ค๋ฅธ ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด ๋ค์์ ๊ฐ์ ํฐ๋ฏธ๋ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค:
Non-interactive ๋ชจ๋์์๋ ์ ธ์์ ํ์ผ์ด๋ pipe๋ฅผ ํตํ์ฌ ๋ช ๋ น์ ์ฝ๊ณ ์คํํฉ๋๋ค. Interpreter๋ ํ์ผ์ด ๋๋๊ฒ ๋๋ฉด ์ ธ ํ๋ก์ธ์ค๋ ์ธ์ ์ ์ข ๋ฃํ๊ณ ๋ถ๋ชจ ํ๋ก์ธ์ค๋ก ๋์๊ฐ๋๋ค.
๋ค์ ๋ช ๋ น์ผ๋ก non-interactive ๋ชจ๋๋ก ์ ธ์ ์คํ์ํฌ ์ ์์ต๋๋ค:
sh /path/to/script.sh
bash /path/to/script.sh
์ ์์ ์์ script.sh
๋ ์
ธ ์ธํฐํ๋ฆฌํฐ๊ฐ ์ ์ ์๋ ๋ช
๋ น์ผ๋ก ๊ตฌ์ฑ๋ ์ผ๋ฐ ํ์ผ์ด๊ณ sh
, bash
๋ ์
ธ ์ธํฐํ๋ฆฌํฐ ํ๋ก๊ทธ๋จ์
๋๋ค. ๋น์ ์ script.sh
ํ์ผ์ ํธํ ์๋ํฐ๋ก ์์ฑํ ์ ์์ต๋๋ค. (์, vim, nano, Sublime Text, Atom ๋ฑ)
chmod
๋ช
๋ น์ ํตํด ์คํํ์ผ๋ก ๋ณ๊ฒฝํด์ผ ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ๊ฒ ์คํํ ์ ์์ต๋๋ค.
chmod +x /path/to/script.sh
๋ํ ์คํฌ๋ฆฝํธ ์ฒซ ์ค์ ํ์ผ์์ ์คํํ๋ ๋ฐ ์ฌ์ฉ๋๋ ํ๋ก๊ทธ๋จ์ ๋ค์๊ณผ ๊ฐ์ด ํ์ํด์ผ ํฉ๋๋ค:
#!/bin/bash
echo "Hello, world!"
bash
๋ณด๋ค sh
๊ฐ ๋ ์ข๋ค๋ฉด, #!/bin/bash
๊ตฌ๋ฌธ์ #!/bin/sh
๋ก ๋ณ๊ฒฝํ๋ฉด ๋ฉ๋๋ค. ์ด #!
๋ฌธ์์ด์ shebang๋ก ์๋ ค์ ธ ์์ต๋๋ค. ๊ทธ๋ผ ์ด์ ๋ค์์ฒ๋ผ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์ ์์ต๋๋ค:
/path/to/script.sh
์์์ ์์ฑํ ๊ฐ๋จํ trick์ echo
๋ช
๋ น์ ์ด์ฉํ์ฌ ํฐ๋ฏธ๋์ ํ
์คํธ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
Shebang ๋ผ์ธ์ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์ ๋ ฅํ ์๋ ์์ต๋๋ค:
#!/usr/bin/env bash
echo "Hello, world!"
์ด shebang์์ ์ข์ ์ ์ ์์คํ
PATH
ํ๊ฒฝ ๋ณ์๋ก ์ง์ ๋ ๊ฒ์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ก๊ทธ๋จ์ (์ฌ๊ธฐ์๋ bash
) ์คํํ๋ค๋ ๊ฒ์
๋๋ค. ์ด๊ฒ์ ํ์ผ ์์คํ
์์ ํ๋ก๊ทธ๋จ path๊ฐ ๊ฐ์ง ์์ ์ ์๊ธฐ์ ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ๋ณด๋ค๋ ๋ฐ๋์งํฉ๋๋ค. ์์คํ
PATH
๊ฐ ๋ค๋ฅธ ๋ฒ์ ์ ๋ํ ํ๋ก๊ทธ๋จ์ผ๋ก ํ๊ธฐํ๊ณ ์์ ๋ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ธฐ์กด ๋ฒ์ ์ธ bash
๋ฅผ ์ ์งํ๋ฉด์ ์๋ก์ด ๋ฒ์ ์ผ๋ก ์ค์นํ๊ณ PATH
๋ณ์์ ์๋ก์ด ์์น๋ฅผ ์
๋ ฅํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ธฐ์กด bash
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ #!/bin/bash
๋ฅผ ์ฌ์ฉํ๊ณ ์๋ก์ด ๋ฒ์ ์ ์ฌ์ฉํ๊ธฐ ์ํด #!/usr/bin/env bash
๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๋ชจ๋ ๋ช
๋ น์ exit code๋ฅผ ๋ฐํํฉ๋๋ค (return status ๋๋ exit status). ์ ์ ์๋ํ ๋ช
๋ น์ ํญ์ 0
(zero-code)๋ฅผ, ์ ์ ์๋์ด ์๋ ๊ฒฝ์ฐ 0์ด ์๋ ๊ฐ(error code)์ ๋ฐํํฉ๋๋ค. ์คํจ ์ฝ๋๋ 1์์ 255๊น์ง์ธ ์์ ์ ์์ด์ด์ผ ํฉ๋๋ค.
์คํฌ๋ฆฝํธ๋ก ์ฌ์ฉํ ๋ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ์ ์๋ ์ ์ฉํ ๋ช
๋ น ์ค ํ๋๋ exit
์
๋๋ค. ์ด ๋ช
๋ น์ ์คํ๋๊ณ ์๋ ๋ช
๋ น์ ์ข
๋ฃํ๊ณ ์
ธ์ ์ข
๋ฃ ์ฝ๋๋ฅผ ์ ๋ฌํ๋ ๋ฐ ์ฌ์ฉํฉ๋๋ค. ์ธ์ ์์ด exit
์ฝ๋๋ฅผ ์คํํ๋ฉด ์คํ ์ค์ธ ์คํฌ๋ฆฝํธ๊ฐ ์ข
๋ฃ๋ ํ exit
์ ๋ง์ง๋ง์ผ๋ก ์คํํ ๋ช
๋ น์ด ๋ฐํํ ์ข
๋ฃ ์ฝ๋๋ฅผ ๋ฐํํ๊ฒ ๋ฉ๋๋ค.
ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃ๋๋ฉด ์
ธ์ $?
ํ๊ฒฝ๋ณ์์ ๊ทธ exit code๊ฐ ํ ๋น๋ฉ๋๋ค. $?
๋ณ์๋ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋์๋์ง๋ฅผ ํ์ธํ ์ ์๋ ๊ธฐ๋ณธ ํ
์คํธ ๋ฐฉ๋ฒ์
๋๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก ์ฐ๋ฆฌ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ข
๋ฃํ๊ธฐ ์ํด exit
๋ฅผ ์ฌ์ฉํ ์ ์๊ณ , return
๋ช
๋ น์ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ์ข
๋ฃํ๊ณ caller์๊ฒ exit code๋ฅผ ๋ฐํํฉ๋๋ค. ํจ์ ๋ด๋ถ์์ exit
๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ํจ์๋ฅผ ์ข
๋ฃ_ํ๊ณ _ ํ๋ก๊ทธ๋จ์ ์ฃฝ์
๋๋ค.
์คํฌ๋ฆฝํธ๋ _์ฃผ์_์ ํฌํจํด๋ ๋ฉ๋๋ค. ์ฃผ์์ shell
์ธํฐํ๋ฆฌํฐ์์ ๋ฌด์๋๋ ํน๋ณํ ๋ฌธ์ฅ์
๋๋ค. #
์ผ๋ก ์์ํ๋ฉฐ ์ค ๋ฐ๊ฟ์ด ์๊ธฐ ์ ๊น์ง ์์ฑ๋ ๋ด์ฉ์ ์ฃผ์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด:
#!/bin/bash
# This script will print your username.
whoami
Tip: ์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ง๋ค์๋์ง์ ๋ํ ๋ด์ฉ์ ์ฃผ์์ ๋ฃ์ด์ผ ๋ฉ๋๋ค.
๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ฒ๋ผ ๋ณ์๋ฅผ ์์ฑํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Bash๋ ๋ฐ์ดํฐ ํ์ ์ ์ ์ ์์ต๋๋ค. ๊ทธ๋์ ๋ณ์๋ ์ค์ง ์ซ์(numbers)๋ ํ๋ ์ด์์ ๋ฌธ์์ด(string)๋ก ํ ๋นํ ์ ์์ต๋๋ค. ๋ณ์๋ 3๊ฐ์ง๋ก ๋ง๋ค ์ ์์ต๋๋ค: ์ง์ญ ๋ณ์, ํ๊ฒฝ ๋ณ์, positional arguments ๋ณ์์ ๋๋ค.
**์ง์ญ ๋ณ์ (Local variables)**๋ ๋จ์ผ ์คํฌ๋ฆฝํธ ๋ด์ ์กด์ฌํ๋ ๋ณ์์ ๋๋ค. ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ด๋ ์คํฌ๋ฆฝํธ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
์ง์ญ ๋ณ์๋ =
๊ธฐํธ๋ฅผ ์ด์ฉํ์ฌ ํ ๋นํ ์ ์์ต๋๋ค. ๊ท์น์ =
๊ณผ ๊ฐ ์ฌ์ด์๋ ๊ณต๋ฐฑ์ด ์์ด์๋ ์ ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ๋ถ๋ฅผ ๋๋ $
๊ธฐํธ๋ฅผ ์ด์ฉํ์ฌ ๋ถ๋ฆ
๋๋ค. ์๋ฅผ ๋ค์ด:
username="denysdovhan" # declare variable
echo $username # display value
unset username # delete variable
๋ํ local
ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋จ์ผ ํจ์์ ์ง์ญ ๋ณ์๋ฅผ ์ ์ธ ํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํจ์๊ฐ ์ข
๋ฃํ ๋ ๋ณ์๊ฐ ํ์๋์ง ์์ต๋๋ค.
local local_var="I'm a local value"
**ํ๊ฒฝ ๋ณ์ (Environment variables)**๋ ํ์ฌ ์
ธ ์น์
์์ ์คํ๋๊ณ ์๋ ํ๋ก๊ทธ๋จ์ด๋ ์คํฌ๋ฆฝํธ์์ ์ ๊ทผํ ์ ์๋ ๋ณ์์
๋๋ค. ์ง์ญ ๋ณ์์ ๊ฐ์ดํ์ฌ ๋ง๋ค์ง๋ง, export
ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑํฉ๋๋ค.
export GLOBAL_VAR="I'm a global variable"
Bash์์๋ ์ ์ญ ๋ณ์๊ฐ ์ข ์์ต๋๋ค. ์์ฃผ ์ด๋ฐ ๋ณ์๋ฅผ ํ์ธํ๊ธฐ ์ํด ์๋ํ๊ฐ ์์ต๋๋ค:
๋ณ์ | ์ค๋ช |
---|---|
$HOME |
ํ์ฌ ์ฌ์ฉ์ ํ ๋๋ ํฐ๋ฆฌ. |
$PATH |
์ ธ์์ ์ฌ์ฉํ๋ ๋ช ๋ น์ด๋ฅผ ์ฐพ๊ธฐ ์ํ ์์น. ์ฝ๋ก ์ผ๋ก ๋ชฉ๋ก์ ๊ตฌ๋ถํจ. |
$PWD |
ํ์ฌ ์์ ์ค์ธ ๋๋ ํฐ๋ฆฌ. |
$RANDOM |
0 ~ 32767 ์ฌ์ด์ ๋ ๋ค ์ธํธ๊ฐ. |
$UID |
ํ์ ์ฌ์ฉ์์ ์ค์ฌ ์ฌ์ฉ์ ID, ์ซ์๋ก ํ๊ธฐ๋จ. |
$PS1 |
์ฒซ๋ฒ์งธ ํ๋กฌํํธ ๋ฌธ์์ด. |
$PS2 |
๋๋ฒ์งธ ํ๋กฌํํธ ๋ฌธ์์ด. |
๋ค์์ ๋งํฌ์์ bash์ ์๋ ํ๊ฒฝ ๋ณ์ ํ์ฅ ๋ชฉ๋ก์ ํ์ธํ ์ ์์ต๋๋ค.
**์์น ๋งค๊ฐ๋ณ์ (Positional parameters)**๋ ํจ์๋ ๊ฐ์ ๊ตฌํ๊ณ ํ ๋น๋ ์์น์ ๋ํ ๊ฐ์ ํ ๋นํฉ๋๋ค. ํจ์ ๋ด๋ถ์ ์๋ ๊ฒฝ์ฐ, ๋ค์ ํ์ ๋์ด๋ ์์น ๋งค๊ฐ ๋ณ์์ ๊ธฐํ ํน๋ณํ ๋ณ์์ ๋ํ ์๋ฏธ๋ฅผ ๋ณด์ฌ์ค๋๋ค. (์ญ์์ฃผ: Argument๋ผ๊ณ ๋ถ๋ฆฌ๋ ๋งค๊ฐ๋ณ์๋ค์ด๋ค.)
๋งค๊ฐ๋ณ์ | ์ค๋ช |
---|---|
$0 |
์คํฌ๋ฆฝํธ ์ด๋ฆ. |
$1 โฆ $9 |
1 ~ 9๊น์ง ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก ์์. |
${10} โฆ ${N} |
10 ~ N๊น์ง ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก ์์. |
$* or $@ |
$0 ์ ์ ์ธํ ๋ชจ๋ ์์น ๋งค๊ฐ๋ณ์. |
$# |
๋งค๊ฐ๋ณ์์ ๋ํ ์ซ์, $0 ๋ฅผ ์ ์ธํ๊ณ . |
$FUNCNAME |
ํจ์ ์ด๋ฆ (ํจ์ ๋ด์์๋ง ๊ฐ์ ๊ฐ์ง๋๋ค) |
๋ค์ ์์ ๋ฅผ ์์น ๋งค๊ฐ๋ณ์๋ก ๋ํ๋ด๋ฉด $0='./script.sh'
, $1='foo'
, $2='bar'
:
./script.sh foo bar
๋ณ์์ ๊ธฐ๋ณธ ๊ฐ์ด ์กด์ฌํ ์ ์์ต๋๋ค. ๋ค์ ๊ตฌ๋ฌธ์ผ๋ก ํด๋น ๊ฐ์ ์ ์ํ๋ฉด ๊ฐ๋ฅํฉ๋๋ค:
# if variables are empty, assign them default values
: ${VAR:='default'}
: ${$1:='first'}
# or
FOO=${FOO:-'default'}
_Expansions(ํ์ฅ or ์ ๊ฐ์)_์ _token_์ผ๋ก ๋๋ ์ง ํ ์ปค๋ฉ๋ ๋ผ์ธ์์ ์คํ๋ฉ๋๋ค. ๊ณ์ฐ ์ฐ์ ์ฐ์ฐ ๋ฉ์ปค๋์ฆ์์ ๋ค๋ฅธ ๋จ์ด๋ค์ ๋ช ๋ น์ด ์คํ๋๊ณ ๊ฐ์ด ์ ์ฅ๋ฉ๋๋ค.
์ฌ๊ธฐ์ ํฅ๋ฏธ๊ฐ ์๋ค๋ฉด more about shell expansions๋ฅผ ๋ณด์ญ์์ค.
์ค๊ดํธ expansion์ ์์์ ๋ฌธ์์ด์ ์์ฑํ ์ ์์ต๋๋ค. _Filename expansion_๊ณผ ๋น์ทํฉ๋๋ค. ์๋ก:
echo beg{i,a,u}n # begin began begun
๋ํ ์ค๊ดํธ expansion๋ ๋ฃจํ์์ ๋ฐ๋ณตํ ๋ฒ์๋ฅผ ์์ฑํ ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
echo {0..5} # 0 1 2 3 4 5
echo {00..8..2} # 00 02 04 06 08
๋ช
๋ น ์นํ์ ์ฐ๋ฆฌ๊ฐ ๋ช
๋ น์ ๋ํ ๊ฐ์ ๊ตฌํ๊ณ ๋ค๋ฅธ ๋ช
๋ น์ด๋ ๋ณ์๋ฅผ ํ ๋นํ๋๋ฐ ๊ทธ ๊ฐ์ ํ ๋นํ ์ ์์ต๋๋ค. ๋ช
๋ น์ ``
์ด๋ $()
๋ก ๋ฌถ์์ ๋ ๋ช
๋ น์ด๋ก ์นํ์ด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค:
now=`date +%T`
# or
now=$(date +%T)
echo $now # 19:08:26
Bash์์์ ์ฐ์ ์ฐ์ฐ์ ์์ ๋กญ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์์์ธ ๊ฒฝ์ฐ์ $(())
๋ก ๋ฌถ์ด ์ฌ์ฉํฉ๋๋ค. ์ฐ์ expansion ํ์์:
result=$(( ((10 + 5*3) - 7) / 2 ))
echo $result # 9
์ฐ์ expansion์์ ๋ณ์๋ ์ผ๋ฐ์ ์ผ๋ก $
์ ๋์ฌ ์์ด ์ฌ์ฉํฉ๋๋ค:
x=4
y=7
echo $(( x + y )) # 11
echo $(( ++x + y++ )) # 12
echo $(( x + y )) # 13
ํฐ๋ฐ์ดํ์ ์์๋ฐ์ดํ ์ฌ์ด์๋ ์ค์ํ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ํฐ๋ฐ์ดํ ์์์ ๋ณ์๋ ๋ช ๋ น ์นํ์ด ์งํ๋ฉ๋๋ค. ์์๋ฐ์ดํ ์์์๋ ๊ทธ๋ ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด:
echo "Your home: $HOME" # Your home: /Users/<username>
echo 'Your home: $HOME' # Your home: $HOME
๊ณต๋ฐฑ์ด ํฌํจ๋์ด์๋ ๊ฒฝ์ฐ, ๋ฐ์ดํ ์์ ์ง์ญ ๋ณ์์ ํ๊ฒฝ ๋ณ์ ํ์ฅ์ ์ฃผ์ํฉ๋๋ค. ์ง๋ฃจํ ์์ ๋ก echo
๋ฅผ ์ด์ฉํ์ฌ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ์ ๋ํ์ฌ ์ถ๋ ฅํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค:
INPUT="A string with strange whitespace."
echo $INPUT # A string with strange whitespace.
echo "$INPUT" # A string with strange whitespace.
์ฒซ ๋ฒ์งธ echo
๋ $INPUT ๋ณ์์ ์๋ ๋จ์ด๋ค์ 5๊ฐ์ธ ๋ณ์๋ก ์ธ์ํ์ฌ ํ ์นธ์ฉ ๋์ echo
๋ก ์ถ๋ ฅํฉ๋๋ค. ๋ ๋ฒ์งธ echo
๋ ๊ณต๋ฐฑ์ ํฌํจํ $INPUT ๋ณ์ ์ ์ฒด ๊ฐ์ ๋จ์ผ ์ธ์๋ก ๋ฐ์๋ค์ฌ ์ถ๋ ฅํฉ๋๋ค.
์ด์ ๋ ๋ณต์กํ ๊ฒฝ์ฐ๋ฅผ ๋ด ์๋ค:
FILE="Favorite Things.txt"
cat $FILE # attempts to print 2 files: `Favorite` and `Things.txt`
cat "$FILE" # prints 1 file: `Favorite Things.txt`
์ด๋ จ ๊ฒฝ์ฐ, Favorite-Things.text
์ ๊ฐ์ ์ด๋ฆ์ ํ์ผ ์ด๋ฆ์ ๋ณ๊ฒฝํด์ ํด๊ฒฐํ ์ ์์ง๋ง, ํ๊ฒฝ ๋ณ์, ์์น ๋งค๊ฐ๋ณ์, ๋ค๋ฅธ ๋ช
๋ น (find
, cat
๋ฑ)์ ์ด์ฉํ์ฌ ์ถ๋ ฅํ๋ ๊ฒ์ ํ์ธํด์ผ ๋ฉ๋๋ค. ๋ง์ฝ ์
๋ ฅ๊ฐ์ ๊ณต๋ฐฑ์ด ํฌํจ๋์ด ์์์ง๋ ๋ชจ๋ฅธ๋ค๋ฉด ๋ฐ์ดํ๋ก ๊ฐ์๋๋ค.
๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ค์ฒ๋ผ bash์์ ๋ฐฐ์ด(array)๋ ์ฌ๋ฌ ๊ฐ์ ์ฐธ์กฐํ ์ ์๋๋ก ํด์ฃผ๋ ๋ณ์์ ๋๋ค. Bash์์ ๋ฐฐ์ด์ zero-based์ ๋๋ค. ์ด๊ฑด ๋ฐฐ์ด ์ฒซ ์์ ์ธ๋ฑ์ค๊ฐ 0์ด๋ผ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๋ฐฐ์ด์ ์ฌ์ฉํ ๋, ํน๋ณํ ํ๊ฒฝ ๋ณ์์ธ IFS
๋ฅผ ์กฐ์ฌํด์ผ ํฉ๋๋ค. IFS, Input Field Separator ๋ผ ๋ถ๋ฆฌ๋ ์ด ํ๊ฒฝ ๋ณ์๋ ๋ฐฐ์ด ์์๋ฅผ ๊ตฌ๋ณํ๋ ๋ฌธ์์
๋๋ค. ๊ธฐ๋ณธ ๊ฐ์ ๋น ์คํ์ด์ค ๊ฐ์
๋๋ค. IFS=' '
.
Bash๋ ๋จ์ํ๊ฒ ๋ฐฐ์ด ๋ณ์์ ์ธ๋ฑ์ค ๊ฐ์ ํ ๋นํ์ฌ ๋ณ์๋ฅผ ์์ฑํฉ๋๋ค:
fruits[0]=Apple
fruits[1]=Pear
fruits[2]=Plum
๋ํ ๋ฐฐ์ด ๋ณ์๋ ์ฌ๋ฌ ๊ฐ์ง๋ฅผ ํจ๊ป ํ ๋นํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค:
fruits=(Apple Pear Plum)
๊ฐ ๋ฐฐ์ด ์์๋ ๋ค๋ฅธ ๋ณ์์ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค:
echo ${fruits[1]} # Pear
์ ์ฒด ๋ฐฐ์ด์์ ์ธ๋ฑ์ค๋ฅผ ๋์ ํด์ *
, @
๋ก ํ์ฅํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค:
echo ${fruits[*]} # Apple Pear Plum
echo ${fruits[@]} # Apple Pear Plum
์ด ๋ ์์ ์๋ ์ค์ํ๊ณ ๋ฏธ๋ฌํ ์ฐจ์ด๊ฐ ์์ต๋๋ค: ๊ณต๋ฐฑ์ ๊ฐ์ง๊ณ ์๋ ๋ฐฐ์ด ์์๊ฐ ์๋ ๊ฒฝ์ฐ:
fruits[0]=Apple
fruits[1]="Desert fig"
fruits[2]=Plum
๋ฐฐ์ด ๊ฐ ์์๋ฅผ ๋ค๋ฅธ ํ์ ์ถ๋ ฅํ๊ณ ์ถ๊ธฐ์ printf
๋ด์ฅ ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค:
printf "+ %s\n" ${fruits[*]}
# + Apple
# + Desert
# + fig
# + Plum
์... Desert
์ fig
๊ฐ ์ ๋ค๋ฅธ ํ์ ์ถ๋ ฅ์ด ๋๋ ๊ฑธ๊น์? ๋ฐ์ดํ๋ฅผ ์ฌ์ฉํด๋ด
์๋ค:
printf "+ %s\n" "${fruits[*]}"
# + Apple Desert fig Plum
์ด์ ๋ ์ ๋ถ ํ ํ์ ์ถ๋ ฅ์ด ๋๋๊ตฐ์! ์ด์ ${fruits[@]}
์ฐจ๋ก์
๋๋ค:
printf "+ %s\n" "${fruits[@]}"
# + Apple
# + Desert fig
# + Plum
ํฐ๋ฐ์ดํ ๋ด์์ ๋ฐฐ์ด ์์ ์๋ ๊ฐ ์์๋ค์ ๋ค๋ฅธ ์ธ์๋ก ${fruits[@]}
์ถ๋ ฅ๋ฉ๋๋ค. ์ฌ๊ธฐ์ ๋ฐฐ์ด ์์์ ํฌํจ๋ ๊ณต๋ฐฑ์ ์ ์ง๋ฉ๋๋ค.
๋ํ slice ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฐ์ด ์ฌ๋ผ์ด์คํ ์ ์์ต๋๋ค:
echo ${fruits[@]:0:2} # Apple Desert fig
์ด ์์ ๋ ${fruits[@]}
๋ ๋ฐฐ์ด ์ ์ฒด๋ฅผ ๋ํ๋ด๊ณ , :0:2
๋ ์ธ๋ฑ์ค 0์์ ์์ํด์ 2๋ฒ์งธ ๊ฐ๊น์ง ์ฌ๋ผ์ด์คํ์ฌ ์ถ๋ ฅํ๋ผ๋ ์๋ฏธ์
๋๋ค.
๋ฐฐ์ด์ ์์๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ์ฌ๋ฌ ๊ฐ์ ๊ฐ์ด ํ ๋นํ๋ ๊ฒฝ์ฐ์๋ ๋ ์ ์ฉํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ค์์ฒ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
fruits=(Orange "${fruits[@]}" Banana Cherry)
echo ${fruits[@]} # Orange Apple Desert fig Plum Banana Cherry
์ ์์ ๋ ${fruits[@]}
๋ก ๋ชจ๋ ๋ฐฐ์ด ๊ฐ๋ค์ ๋ถ๋ฌ์ค๊ณ , ์ถ๊ฐ๋ ๋ด์ฉ๊ณผ ๊ฐ์ด ์๋ก์ด ๋ฐฐ์ด์ ์์ฑํ ๋ค์ fruits
๋ณ์์ ํ ๋นํฉ๋๋ค.
๋ฐฐ์ด์์ ์์๋ฅผ ์ ์ธํ๋ ค๋ฉด unset
๋ช
๋ น์ ์ฌ์ฉํฉ๋๋ค:
unset fruits[0]
echo ${fruits[@]} # Apple Desert fig Plum Banana Cherry
Bash๋ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ๋ค๊ณผ ์ถ๋ ฅ์ ์กฐ์ํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. Stream์ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ด๋ ํ์ผ์ ํ๋ก๊ทธ๋จ ์ถ๋ ฅ์ ์ ์กํ์ฌ ๋ก๊ทธ๋ฅผ ์์ฑํ๊ฑฐ๋ ์ํ๋ ์ด๋ค ์์ ์ด๋ ํ ์ ์์ต๋๋ค.
Pipe๋ ์ปจ๋ฒ ์ด์ด๋ฅผ ๋ง๋ค์ด ๋ช ๋ น ์คํ์ ์ ์ดํ ์ ์๋๋ก ํฉ๋๋ค.
์ด ๊ฐ๋ ฅํ๊ณ ์ ๊ตํ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํฉ๋๋ค.
Bash๋ ์ ๋ ฅ์ ๋ฐ์ ์ฐจ๋ก๋ก ์ถ๋ ฅ์ ๋ณด๋ด๊ฑฐ๋ ๋ฌธ์ streams ํฉ๋๋ค. ์ด๋ฐ stream์ ํ์ผ์ด๋ ๋ค๋ฅธ ๊ฒ์ผ๋ก ๋ฆฌ๋ค์ด๋ ์ ๋ ์ ์์ต๋๋ค.
์ฌ๊ธฐ 3๊ฐ ์์ ์๊ฐ ์์ต๋๋ค:
Code | Descriptor | ์ค๋ช |
---|---|---|
0 |
stdin |
ํ์ค ์ ๋ ฅ. |
1 |
stdout |
์ค ์ถ๋ ฅ. |
2 |
stderr |
์ค๋ฅ ์ถ๋ ฅ. |
๋ฆฌ๋๋ ์ ์ ๋ช ๋ น์๋ฅผ ๋ํ ์ถ๋ ฅ๊ฐ์ด ์ด๋๋ก ๊ฐ ๊ฒ์ธ๊ฐ, ๋ช ๋ น์ ๋ํ ์ ๋ ฅ๊ฐ์ด ์ด๋์ ์ฌ ๊ฒ์ธ๊ฐ์ ๋ํ ์ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํด์ค๋๋ค. Stream์์ ๋ฆฌ๋๋ ์ ์์ํด ๋ค์๊ณผ ๊ฐ์ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค:
์ฐ์ฐ์ | ์ค๋ช |
---|---|
> |
์ถ๋ ฅ ์ ์ก |
&> |
์ถ๋ ฅ๊ณผ ์ค๋ฅ ์ถ๋ ฅ ์ ์ก |
&>> |
์ถ๋ ฅ๊ณผ ์ค๋ฅ ์ถ๋ ฅ์ ์ ์ก์ง์ ์ถ๊ฐ |
< |
์ ๋ ฅ ์ ์ก |
<< |
์ ๋ฌธ์ syntax |
<<< |
์ฌ๊ธฐ ๋ฌธ์์ด |
๋ฆฌ๋๋ ์ ์ ์ฌ์ฉํ๋ ์์ ์กฐ๊ธ:
# output of ls will be written to list.txt
ls -l > list.txt
# append output to list.txt
ls -a >> list.txt
# all errors will be written to errors.txt
grep da * 2> errors.txt
# read from errors.txt
less < errors.txt
ํ์ผ๋ฟ๋ง ์๋๋ผ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์์๋ ํ์ค ์คํธ๋ฆผ ๋ฆฌ๋๋ ์ ์ ํ ์ ์์ต๋๋ค. Pipes๋ฅผ ์ด์ฉํ์ฌ ํ๋ก๊ทธ๋จ ์ถ๋ ฅ์ ๋ค๋ฅธ ๊ณณ ์ ๋ ฅ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ค์ ์์์์๋ command1
์ถ๋ ฅ์ command2
๋ก ๋ณด๋ด๊ณ , ๊ทธ ์ถ๋ ฅ์ ๋ค์ command3
์
๋ ฅ์ผ๋ก ๋ณด๋
๋๋ค:
command1 | command2 | command3
์ด๋ฐ ๊ตฌ์กฐ๋ฅผ ํ์ดํ๋ผ์ธ ์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
์ฌ์ค ๋ช ๊ฐ์ง ํ๋ก๊ทธ๋จ์ ํตํด์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ls -l
๋ก ์ถ๋ ฅํ ๊ฐ์์ grep
๋ช
๋ น์ ์ด์ฉํ์ฌ .md
ํ์ฅ์๋ฅผ ๊ฐ์ง ํ์ผ๋ง ์ถ๋ ฅํ ๋ค less
ํ๋ก๊ทธ๋จ์ผ๋ก ์ถ๋ ฅํด์ค๋๋ค:
ls -l | grep .md$ | less
ํ์ดํ๋ผ์ธ์์ ์ข ๋ฃ ์ํ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ง์ง๋ง ๋ช ๋ น์ด ๋๋๋ ์์ ์ ๋๋ค. ํ์ดํ๋ผ์ธ์์ ์๋ ์ค์ธ ๋ชจ๋ ๋ช ๋ น์ด ์๋ฃ๋ ๋๊น์ง ์ ธ ์ํ๋ฅผ ๋ฐํํ์ง ์์ต๋๋ค. ํ์ดํ๋ผ์ธ์ผ๋ก ์ฐ๊ฒฐ๋ ๋ช ๋ น ์ค ํ๋๊ฐ ์คํจํ์์ ๋, ์ฐ๊ฒฐ๋ ํ์ดํ๋ผ์ธ์ด ๋ชจ๋ ์คํจ๋ก ์ค์ ํ๊ณ ์ถ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด pipefail ์ต์ ์ ์ค์ ํด์ผ ํฉ๋๋ค:
set -o pipefail
๋ช
๋ น์ด ๋์ด์ ;
, &
, &&
, ||
์ฐ์ฐ์๋ฅผ ์ด์ฉํ์ฌ ํ๋ ์ด์ ํ์ดํ๋ผ์ธ์ ๋ํ ์์๋ฅผ ๋ํ๋
๋๋ค.
๋ช
๋ น์ด ์ ์ด ์ฐ์ฐ์ &
์ ์ํด์ ์ข
๋ฃ๋ ๊ฒฝ์ฐ, ์
ธ์ ์๋ธ ์
ธ์์ ๋น๋๊ธฐ์ ์ผ๋ก ๋ช
๋ น์ ์คํํฉ๋๋ค. ๋ค๋ฅธ ๋ง๋ก ํ์๋ฉด, ๋ช
๋ น์ด ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํ๋ฉ๋๋ค.
;
๋ก ๊ตฌ๋ถ๋ ๋ช
๋ น์ ์ฐจ๋ก๋ก ์คํ๋ฉ๋๋ค: ์ฐจ๋ก๋ก. ์
ธ์ ๊ฐ ๋ช
๋ น์ด ์ข
๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค.
# command2 will be executed after command1
command1 ; command2
# which is the same as
command1
command2
&&
์ ||
๋ก ๊ตฌ๋ถ๋ ๋ช
๋ น์ด ๋์ด์ ๊ฐ๊ฐ _AND_์ OR ๋ชฉ๋ก์ด๋ผ๊ณ ํฉ๋๋ค.
_AND_list_๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
# command2 will be executed if, and only if, command1 finishes successfully (returns 0 exit status)
command1 && command2
_OR-list_๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
# command2 will be executed if, and only if, command1 finishes unsuccessfully (returns code of error)
command1 || command2
AND ๋๋ OR ๋ช ๋ น์ด ๋์ด์์ ๋ฐํ ์ฝ๋๋ ๋ง์ง๋ง์ผ๋ก ์คํํ ๋ช ๋ น์ ๋ํ ์ข ๋ฃ ์ํ์ ๋๋ค.
๋ค๋ฅธ ์ธ์ด๋ค๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก Bash ์กฐ๊ฑด๋ฌธ์ ์ด๋ค ์์
์ ์ํํ ์ง์ ๋ํด์ ๊ฒฐ์ ํฉ๋๋ค. ๊ฒฐ๊ณผ๋ [[ ]]
๋ก ๋ฌถ์ด์ผ์ง๋ง ํํ์ ํ๊ฐํ์ฌ ๊ฒฐ์ ๋ฉ๋๋ค.
์กฐ๊ฑด์์ &&
์ ||
์ฐ์ฐ์๋ฅผ ์ด์ฉํ์ฌ _AND_์ _OR_๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด์ธ ๋ค์ํ ํํ์ ์ด์ฉํ์ฌ ํ์ธํ ์ ์์ต๋๋ค.
๋ ๊ฐ์ง ์กฐ๊ฑด๋ฌธ์ด ์์ต๋๋ค: if
๋ฌธ๊ณผ case
๋ฌธ.
[[ ]]
(๋๋ sh
์์๋ [ ]
) ์์ ์๋ ์์ ํ
์คํธ ๋ช
๋ น์ด๋ primaries๋ผ ๋ถ๋ฆ
๋๋ค. ์ด ์์๋ค์ ์กฐ๊ฑด์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ค ์ ์๋๋ก ๋์์ค๋๋ค. ๋ค์ ํ
์ด๋ธ์์๋ sh
์์ ์ฌ์ฉํ ์ ์๋๋ก [ ]
๋ฅผ ์ด์ฉํ์ฌ ๋ํ๋์ต๋๋ค. ์ฌ๊ธฐ์ bash์์ ์ด์ค ๋๊ดํธ์ ๋๊ดํธ์ ์ฐจ์ด์ ๋ํด์ ์ด์ผ๊ธฐํฉ๋๋ค.
ํ์ผ ์์คํ ์์ ์๋:
Primary | Meaning |
---|---|
[ -e FILE ] |
FILE ์ด ์กด์ฌํ๋ฉด(exist), True |
[ -f FILE ] |
FILE ์ด ์กด์ฌํ๊ณ ์ผ๋ฐ ํ์ผ(regular file)์ด๋ฉด, True. |
[ -d FILE ] |
FILE ์ด ์กด์ฌํ๊ณ ๋๋ ํ ๋ฆฌ(directory)์ด๋ฉด, True. |
[ -s FILE ] |
FILE ์ด ์กด์ฌํ๊ณ ๋น์ด์๋ค(size more than 0)๋ฉด, True. |
[ -r FILE ] |
FILE ์ด ์กด์ฌํ๊ณ ์ฝ๊ธฐ๊ฐ๋ฅํ๋ค(readable)๋ฉด, True. |
[ -w FILE ] |
FILE ์ด ์กด์ฌํ๊ณ ์ฐ๊ธฐ๊ฐ๋ฅํ๋ค(writable)๋ฉด, True. |
[ -x FILE ] |
FILE ์ด ์กด์ฌํ๊ณ ์คํ๊ฐ๋ฅํ๋ค(xecutable)๋ฉด, True. |
[ -L FILE ] |
FILE ์ด ์กด์ฌํ๊ณ ์ฑ๋ณผ๋ฆญ ๋งํฌ(symbolic link)์ด๋ฉด, True. |
[ FILE1 -nt FILE2 ] |
FILE1์ด FILE2 ๋ณด๋ค ์๋ก์ด ํ์ผ์ ๋๋ค. (FILE1 is newer than FILE2.) |
[ FILE1 -ot FILE2 ] |
FILE1์ด FILE2 ๋ณด๋ค ์ค๋๋ ํ์ผ์ ๋๋ค. (FILE1 is older than FILE2.) |
๋ฌธ์์ด์์ ์๋:
Primary | Meaning |
---|---|
[ -z STR ] |
STR ์ด ๋น์์ (๊ธธ์ด๊ฐ 0 (zero)). |
[ -n STR ] |
STR ์ด ๋น์ด์์ง ์์ (๊ธธ์ด๊ฐ 0 ์๋ (non-zero)) |
[ STR1 == STR2 ] |
STR1 ๊ณผ STR2 ๊ฐ ๊ฐ์. |
[ STR1 != STR2 ] |
STR1 ๊ณผ STR2 ๊ฐ ๊ฐ์ง ์์. |
์ฐ์ ์ดํ ์ฐ์ฐ์:
Primary | Meaning |
---|---|
[ ARG1 -eq ARG2 ] |
ARG1 ๋ ARG2 ์ ๊ฐ๋ค (equal). |
[ ARG1 -ne ARG2 ] |
ARG1 ๋ ARG2 ์ ๊ฐ์ง ์๋ค (not equal). |
[ ARG1 -lt ARG2 ] |
ARG1 ๋ ARG2 ๋ณด๋ค ์๋ค (less then). |
[ ARG1 -le ARG2 ] |
ARG1 ๋ ARG2 ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค (less than or equal). |
[ ARG1 -gt ARG2 ] |
ARG1 ๋ ARG2 ๋ณด๋ค ํฌ๋ค (greater than). |
[ ARG1 -ge ARG2 ] |
ARG1 ๋ ARG2 ๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ๋ค (greater than or equal). |
์กฐ๊ฑด์ combining expressions๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐํฉํ ์ ์์ต๋๋ค:
Operation | Effect |
---|---|
[ ! EXPR ] |
EXPR ์ด ๊ฑฐ์ง์ด๋ฉด True. |
[ (EXPR) ] |
EXPR ๊ฐ ๋ฐํ. |
[ EXPR1 -a EXPR2 ] |
๋
ผ๋ฆฌ AND. EXPR1 ์(and) EXPR2 ์กฐ๊ฑด์ด๋ผ๋ฉด True. |
[ EXPR1 -o EXPR2 ] |
๋
ผ๋ฆฌ OR. EXPR1 ๋๋(or) EXPR2 ์กฐ๊ฑด์ด๋ผ๋ฉด True. |
๋ฌผ๋ก ๋ ์ ์ฉํ primaries๊ฐ ์กด์ฌํ๋ฉฐ Bash man pages์์ ๋ ์ฝ๊ฒ ์ฐพ์๋ณผ ์ ์์ต๋๋ค.
if
๋ฌธ์ ๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๊ฐ์ด ์๋ํฉ๋๋ค. ๊ดํธ ์์ ์๋ ํํ์์ด ์ฐธ์ด๋ฉด then
๊ณผ fi
์ฌ์ด ์ฝ๋๊ฐ ์คํ๋ฉ๋๋ค. fi
๋ ์กฐ๊ฑด๋ถ๋ก ์คํ๋๋ ์ฝ๋ ๋์ ๋ํ๋
๋๋ค.
# Single-line
if [[ 1 -eq 1 ]]; then echo "true"; fi
# Multi-line
if [[ 1 -eq 1 ]]; then
echo "true"
fi
๋ง์ฐฌ๊ฐ์ง๋ก if..else
๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
# Single-line
if [[ 2 -ne 1 ]]; then echo "true"; else echo "false"; fi
# Multi-line
if [[ 2 -ne 1 ]]; then
echo "true"
else
echo "false"
fi
๋๋ก๋ if..else
๋ฌธ์ด ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋งํผ ์ถฉ๋ถํ ๊ธฐ๋ฅ์ ํ์ง ๋ชปํ ์๋ ์์ต๋๋ค. ๊ทธ๋ด ๊ฒฝ์ฐ, if..elif..else
๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ค์ ์์ ๋ฅผ ๋ด ์๋ค:
if [[ `uname` == "Adam" ]]; then
echo "Do not eat an apple!"
elif [[ `uname` == "Eva" ]]; then
echo "Do not take an apple!"
else
echo "Apples are delicious!"
fi
๋ค์ด์จ ๊ฐ์ ๋ง๋ ์์
์ ์งํํ ๋, ์ค์ฒฉ๋ if
๋ฌธ๋ณด๋ค ์ ์ฉํ case
๋ฌธ์ ์ด์ฉํ ์ ์์ต๋๋ค. ๋ ๋ณต์กํ ์กฐ๊ฑด์ผ ๋, case
๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํฉ๋๋ค:
case "$extension" in
"jpg"|"jpeg")
echo "It's image with jpeg extension."
;;
"png")
echo "It's image with png extension."
;;
"gif")
echo "Oh, it's a giphy!"
;;
*)
echo "Woops! It's not image!"
;;
esac
๊ฐ case๋ ํจํด๊ณผ ์ผ์นํ๋ ์์
๋๋ค. |
๊ธฐํธ๋ ์ฌ๋ฌ ํจํด์ ๋ถ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ, )
์ฐ์ฐ์๋ ํจํด ๋ชฉ๋ก ๋์ ๋ํ๋
๋๋ค. ์ฒซ ๋ฒ์งธ ๋ช
๋ น๊ณผ ๋ง๋๋ค๋ฉด ์คํ๋ฉ๋๋ค. *
๋ ์ ์๋ ํจํด์ ์ผ์นํ์ง ์๋ ๊ฒ๋ค์ ๋ํ๋ด๊ธฐ ์ํ ํจํด์
๋๋ค. ๋ช
๋ น์ ๋ํ ๊ฐ ๋ธ๋ก์ ;;
์ฐ์ฐ์๋ฅผ ์ด์ฉํ์ฌ ๋ถ๋ฆฌํฉ๋๋ค.
๋๋ ๋๋ผ์ง ์๊ฒ ์ฃ . ๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ค์ฒ๋ผ bash์์ ์ฌ์ฉ๋๋ ๋ฐ๋ณต๋ฌธ์ ์ฃผ๊ฑด ์ ์ด๋ฌธ์ด true์ผ ๋ ๋ฐ๋ณต ์ฒ๋ฆฌ ์ฝ๋ ๋ธ๋ก์ ์งํํฉ๋๋ค.
Bash์์ ๋ฐ๋ณต๋ฌธ์ 4๊ฐ์ง ํ์์ด ์์ต๋๋ค: for
, while
, until
, select
.
for
๋ฌธ์ C ์กฑ๊ณผ ๋งค์ฐ ๋น์ทํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํฉ๋๋ค:
for arg in elem1 elem2 ... elemN
do
# statements
done
๊ฐ ๋ฃจํ๋ฅผ ํต๊ณผํ ๋, arg
์ elem1
์์ elemN
๊น์ง์ ๊ฐ์ด ํ ๋น๋ฉ๋๋ค. ์์ผ๋์นด๋ ๋๋ ์ค๊ดํธ expansions๋ก ๊ฐ์ด์ด๋ ๋ฉ๋๋ค.
๋ํ, ํ ์ค๋ก for
๋ฌธ์ ์์ฑํด์ผ ํ๋ค๋ฉด ๋ค์์ฒ๋ผ do
์์ ์ธ๋ฏธ์ฝ๋ก ์ ๋ถ์ฌ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
for i in {1..5}; do echo $i; done
for..in..do
ํ์์ด ์ด์ํ๋ค๋ฉด ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก C์ ๊ฐ์ ์คํ์ผ๋ก for
๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
for (( i = 0; i < 10; i++ )); do
echo $i
done
๋๋ ํฐ๋ฆฌ์์ ๊ฐ ํ์ผ์ ๊ฐ์ ์์
์ ์งํํ๋ ค๊ณ ํ ๋ for
๋ฌธ์ ์ฌ์ฉํ๋ฉด ํธํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋ .bash
ํ์ผ์ script
ํด๋๋ก ์ฎ๊ธฐ๊ณ ์คํ ๊ถํ์ ์ค๋ค๋ฉด, ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค:
#!/bin/bash
for FILE in $HOME/*.bash; do
mv "$FILE" "${HOME}/scripts"
chmod +x "${HOME}/scripts/${FILE}"
done
while
๋ฐ๋ณต๋ฌธ์ ์กฐ๊ฑด์ ํ
์คํธํ๊ณ _true_๊ฐ ๋ ๋๊น์ง ๋ช
๋ น์ ๋ฐ๋ณตํฉ๋๋ค. ์กฐ๊ฑด์ if..then
์กฐ๊ฑด์์ primary ์ฌ์ฉ๋๋ ๊ฒ๊ณผ ๋ค๋ฅด์ง ์์ต๋๋ค. ๊ทธ๋์ while
๋ฐ๋ณต๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
while [[ condition ]]
do
# statements
done
for
๋ฐ๋ณต๋ฌธ๊ณผ ๊ฐ์ด ๊ฐ์ ์ค์ do
๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์์ ์ธ๋ฏธ์ฝ๋ก ์ ๋ถ์ฌ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
์์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
#!/bin/bash
# Squares of numbers from 0 through 9
x=0
while [[ $x -lt 10 ]]; do # value of x is less than 10
echo $(( x * x ))
x=$(( x + 1 )) # increase x
done
until
๋ฐ๋ณต๋ฌธ์ while
๋ฐ๋ณต๋ฌธ๊ณผ๋ ์ ๋ฐ๋๋ก ์๋ํฉ๋๋ค. while
๊ณผ ๊ฐ์ด ํ
์คํธ ์กฐ๊ฑด์ ํ์ธํ๊ณ ๊ทธ ์กฐ๊ฑด์ด false ๋ ๋๊น์ง ์๋ํฉ๋๋ค:
until [[ condition ]]; do
#statements
done
select
๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉ์ ๋งค๋ด์ผ์ ๊ตฌ์ฑํ ์ ์๋๋ก ๋์์ค๋๋ค. for
๋ฐ๋ณต๋ฌธ๊ณผ ๊ฐ์ ๊ตฌ๋ฌธ์ผ๋ก ๋์ด์์ต๋๋ค:
select answer in elem1 elem2 ... elemN
do
# statements
done
select
์ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ๋ฉด, ์ฐ์๋ ์ซ์๋ค๊ณผ ์คํฌ๋ฆฐ์ ๋ชจ๋ elem1..elemN
์ ์ถ๋ ฅํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก $?
(PS3
๊ฐ)๊ณผ ๊ฐ์ด ๋ณด์
๋๋ค. ์
๋ ฅํ ๋๋ต์ answer
์ ์ ์ฅ๋ฉ๋๋ค. answer
๊ฐ 1..N
์ฌ์ด ์์ธ ๊ฒฝ์ฐ, statements
๊ฐ ์คํ๋๊ณ select
๋ ๋ค์์ ์คํํฉ๋๋ค. ์ฌ๊ธฐ์ break
๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์๋ ์์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
#!/bin/bash
PS3="Choose the package manager: "
select ITEM in bower npm gem pip
do
echo -n "Enter the package name: " && read PACKAGE
case $ITEM in
bower) bower install $PACKAGE ;;
npm) npm install $PACKAGE ;;
gem) gem install $PACKAGE ;;
pip) pip install $PACKAGE ;;
esac
break # avoid infinite loop
done
์ด ์์ ์์๋ ์ฌ์ฉ์์๊ฒ ์ฌ์ฉํ ์ด๋ค ํจํค์ง ๊ด๋ฆฌ์ {s,he}๋ฅผ ๋ฌป์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ํจํค์ง ๊ด๋ฆฌ์๋ฅผ ์ ํํ๊ณ ์ค์นํ ํจํค์ง๋ฅผ ๋ฌป์ต๋๋ค.
์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ ํ์ธํ ์ ์์ต๋๋ค:
$ ./my_script
1) bower
2) npm
3) gem
4) pip
Choose the package manager: 2
Enter the package name: bash-handbook
<installing bash-handbook>
๋ฐ๋ณต๋ฌธ์ด ์ผ๋ฐ์ ์ผ๋ก ๋๋ด๊ฑฐ๋ ํน์ ๋จ๊ณ ์ ์ ๋ฉ์ถ ๋๊ฐ ํ์ํฉ๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์ ์
ธ ๋ด์ฅ ํจ์์ธ break
๊ณผ continue
๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ ๋ค ๋ชจ๋ ๋ฐ๋ณต๋ฌธ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
break
๋ฌธ์ ๋๋๊ธฐ ์ ํ์ฌ ๋ฐ๋ณต๋ฌธ์์ ๋๊ฐ ๋ ์ฌ์ฉํฉ๋๋ค. ์ด๋ฏธ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
continue
๋ฌธ์ ํ๋จ๊ณ๋ฅผ ๋์ด์ ์งํ๋ฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค:
for (( i = 0; i < 10; i++ )); do
if [[ $(( i % 2 )) -eq 0 ]]; then continue; fi
echo $i
done
์ ์์ ๋ฅผ ์คํํ๋ค๋ฉด, 0์์ 9๊น์ง์ ๋ชจ๋ ์ง์๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
์คํฌ๋ฆฝํธ์์ ํจ์๋ฅผ ์ ์ํ๊ณ ๋ถ๋ฌ ์ฌ์ฉ ๊ฐ๋ฅ ํฉ๋๋ค. ๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ฒ๋ผ Bash์์ ํจ์๋ ์ฝ๋ ๋ฉ์ด๋ฆฌ์ง๋ง ์ฐจ์ด๊ฐ ์์ต๋๋ค.
Bash์์ ํจ์๋ ํจ์ _์ด๋ฆ_์ผ๋ก ๊ทธ๋ฃนํํ ๋ช ๋ น์ ๋๋ค. ํจ์๋ฅผ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ๊ณผ ๊ฐ์ด ํธ์ถํ๋ฉฐ, ๊ทธ๋ฅ ์ด๋ฆ์ ์ฌ์ฉํ๋ฉด ํจ์๊ฐ ํธ์ถ๋ฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ํจ์๋ฅผ ์ ์ธํ ์ ์์ต๋๋ค:
my_func () {
# statements
}
my_func # call my_func
ํจ์๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ์ธ์ ํ์ฌ์ผ์ง ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํจ์๋ ์ธ์๋ฅผ ์ทจํด ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ ์ ์์ต๋๋ค -- ์ข
๋ฃ ์ฝ๋. ์ธ์๋ ํจ์๋ด non-interactive ๋ชจ๋์์ ์คํฌ๋ฆฝํธ์ ์ฃผ์ด์ง ์ธ์์ ๊ฐ์ด ์ทจ๊ธ๋ฉ๋๋ค. -- positional parameters๋ฅผ ์ฌ์ฉํด์. ๊ฒฐ๊ณผ ์ฝ๋๋ return
๋ช
๋ น์ ์ฌ์ฉํ์ฌ ๋ฐํํฉ๋๋ค.
ํจ์๊ฐ ์ ์์ ์ผ๋ก ์คํ๋ ๊ฒ์ ๋ํ๋ด๋ ์ด๋ฆ์ ๊ฐ์ง๊ณ 0
์ ๋ฐํํฉ๋๋ค.
# function with params
greeting () {
if [[ -n $1 ]]; then
echo "Hello, $1!"
else
echo "Hello, unknown!"
fi
return 0
}
greeting Denys # Hello, Denys!
greeting # Hello, unknown!
์ด๋ฏธ ์ข
๋ฃ ์ฝ๋์ ๋ํด์ ์ด์ผ๊ธฐํ์์ต๋๋ค. return
๋ช
๋ น์ ์ธ์ ์์ด ๋ง์ง๋ง์ผ๋ก ์คํํ ๋ช
๋ น์ ๋ํ ์ข
๋ฃ ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ return 0
์ผ๋ก ๊ตฌ์ฑํด ๋๋ฉด ์ ์ ์ข
๋ฃ ์ฝ๋๋ก 0
์ ๋ฐํํฉ๋๋ค.
์ ธ์์๋ ์คํฌ๋ฆฝํธ๋ฅผ ๋๋ฒ๊น ํ ์ ์๋ ํด์ ์ ๊ณตํฉ๋๋ค. ๋๋ฒ๊ทธ ๋ชจ๋๋ก ์คํํ๋ ค๋ฉด ์คํฌ๋ฆฝํธ shebang์ ํน๋ณํ ์ต์ ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค:
#!/bin/bash options
์ด ์ต์ ์ ์ ธ ๋์์ ๋ณ๊ฒฝํ๋ ์ค์ ์ ๋๋ค. ๋ค์ ํ์์ ๋์์ด ๋๋ ๊ฒ๋ค์ ๊ดํด ์ค๋ช ํด๋์ต๋๋ค:
Short | Name | ์ค๋ช |
---|---|---|
-f |
noglob | ํ์ผ ์ด๋ฆ ํ์ฅ (globbing)์ ๋นํ์ฑํํฉ๋๋ค. |
-i |
interactive | ์คํฌ๋ฆฝํธ๋ฅผ interactive ๋ชจ๋๋ก ์๋ํฉ๋๋ค. |
-n |
noexec | ๋ช ๋ น์ ์ฝ์ต๋๋ค๋ง ์คํํ์ง๋ ์์ต๋๋ค (๋ฌธ๋ฒ ์ฒดํฌ). |
pipefail | ์ด๋ค ๋ช ๋ น์ด ์ ๋๋ก ์คํ๋์ง ๋ชปํ์ฌ ๋ง์ง๋ง ๋ช ๋ น์ด ์คํจํ ๊ฒ์ด ์๋๋ผ๋ฉด, ํ์ดํ๋ผ์ธ ์ค๋ฅ๋ฅผ ํ์ธํฉ๋๋ค. | |
-t |
โ | ์ฒซ ๋ช ๋ น ํ ์ข ๋ฃํฉ๋๋ค. |
-v |
verbose | ๊ฐ ๋ช
๋ น์ ์คํํ๊ธฐ ์ stderr ๋ฅผ ์ถ๋ ฅํฉ๋๋ค. |
-x |
xtrace | ๊ฐ ๋ช
๋ น์ ์คํํ๊ธฐ ์ ๋ช
๋ น๊ณผ stderr ์ ํ์ฅ ๋ณ์๋ฅผ ์ถ๋ ฅํฉ๋๋ค. |
์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด -x
์ต์
์ ์ฌ์ฉํด ์คํฌ๋ฆฝํธ๋ฅผ ๋ง๋ญ๋๋ค:
#!/bin/bash -x
for (( i = 0; i < 3; i++ )); do
echo $i
done
์ด ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๊ฒ๋๋ฉด ๋ค๋ฅธ ์ ๋ณด๋ค๊ณผ ํจ๊ป stdout
๋ณ์ซ๊ฐ์ ์ถ๋ ฅํฉ๋๋ค:
$ ./my_script
+ (( i = 0 ))
+ (( i < 3 ))
+ echo 0
0
+ (( i++ ))
+ (( i < 3 ))
+ echo 1
1
+ (( i++ ))
+ (( i < 3 ))
+ echo 2
2
+ (( i++ ))
+ (( i < 3 ))
๋๋๋ก ์คํฌ๋ฆฝํธ ์ผ๋ถ๋ฅผ ๋๋ฒ๊น
ํด์ผ ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ set
๋ช
๋ น์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. ์ด ๋ช
๋ น์ผ๋ก ์ต์
์ ํ์ฑํํ๊ณ ๋นํ์ฑํํ ์ ์์ต๋๋ค. ์ฌ์ฉ๋ฒ์ -
์ ์ฌ์ฉํ์ฌ ํ์ฑํ ์ํค๊ณ , +
๋ฅผ ์ฌ์ฉํ์ฌ ๋นํ์ฑํํฉ๋๋ค:
#!/bin/bash
echo "xtrace is turned off"
set -x
echo "xtrace is enabled"
set +x
echo "xtrace is turned off again"
๋๋ ์ด ์์ ํธ๋๋ถ์ด ์ฌ๋ฏธ์๊ณ ๋์์ด ๋์์ผ๋ฉด ํฉ๋๋ค. ๋ ์์ ์ด Bash์ ๋ํ ๊ธฐ๋ณธ์ ์์ง ์๊ธฐ ์ํด ์ด ํธ๋๋ถ์ ์์ฑํ์์ต๋๋ค. ๊ฐ๊ฒฐํ๊ณ ์๋ฏธ ์๋ ๊ฒ์ ๊ธฐ๋กํ๋ ค ํ์์ต๋๋ค๋ง, ์ ์๋์๋ค๋ฉด ์ดํดํด ์ฃผ์ จ์ผ๋ฉด ํฉ๋๋ค.
์ด ํธ๋๋ถ์ bash์ ๋ํ ๋ด ๊ฒฝํ์ ์ด์ผ๊ธฐํฉ๋๋ค. ์ด๊ฒ์ ๊ทธ๋ ๊ฒ ํฌ๊ด์ ์ผ๋ก ์์ ๋์ง ์์๊ธฐ์ ๋ ๋ง์ ๊ฒ์ ์ํ๋ค๋ฉด man bash
๋ฅผ ์คํํด์ ํ์ธํ์ญ์์ค.
์ปจํธ๋ฆฌ๋ทฐ์ ์ ์ ๋์ ์ผ๋ก ํ์ํ๋ฉฐ ์ด๋ค ์ง๋ฌธ์ด๋ ์ด์์ ๋ํด ๋์๊ฒ ์๋ ค์ฃผ์ญ์์ค. ์ด์๋ฅผ ๋ง๋ค์ด์ ๋ง์ด์ฃ .
์ด ํธ๋๋ถ์ ์ฝ์ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
์ฌ๊ธฐ๋ Bash์ ๋ํด์ ๋ ์ ์ ์๋ ๋ฌธ์ ๋ชฉ๋ก์ ๋๋ค:
- Bash man ํ์ด์ง. Bash๊ฐ ์คํ๋๋ ์ฌ๋ฌ ํ๊ฒฝ์์ ๋์๋ง ์์คํ
man
์ ์ฌ์ฉํ์ฌ Bash์ ๊ดํ ๋ด์ฉ์ ํ์ธํ ์ ์์ผ๋ฉฐ, ์คํ ๋ช ๋ น์ด๋man bash
์ ๋๋ค.man
๋ช ๋ น์ ๋ํ ๋ ๋ง์ ๋ด์ฉ์ ํ์ธํ๊ณ ์ถ์ผ๋ฉด The Linux Information Project์์ ํธ์คํ ๋๊ณ ์๋ "The man Command" ์นํ์ด์ง๋ฅผ ํ์ธํ์ญ์์ค. - "Bourne-Again SHell manual"์ ๋ง์ ํ์ (HTML, Info, TeX, PDF, Texinfo)์ผ๋ก ๋์ด์์ต๋๋ค. https://www.gnu.org/์์ ํธ์คํ ๋๊ณ ์์ต๋๋ค. 2016๋ 1์ ํ์ฌ ๋ฒ์ 4.3์ด๋ฉฐ, ๋ง์ง๋ง ์ ๋ฐ์ดํธ๋ 2015๋ 2์ 2์ผ์ ๋๋ค.
- awesome-bash๋ Bash ์คํฌ๋ฆฝํธ์ ๋ฆฌ์์ค์๋ํ ๋ชจ์
- awesome-shell๋ ์ ธ ๋ฆฌ์์ค์ ๋ํ ๋ค๋ฅธ ๋ชจ์
- bash-it ์ผ์ ์ ๋ฌด์์ ์ฌ์ฉํ ์ ธ ์คํฌ๋ฆฝํธ์ ๊ฐ์ธํ๋ ๋ช ๋ น์ ์ฌ์ฉํ์ฌ ๊ฐ๋ฐ๊ณผ ๊ด๋ฆฌ๋ฅผ ์ํ ๊ฐ๋ ฅํ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- dotfiles.github.io๋ ๋ค์ํ dotfile ์ปฌ๋ ์ ๊ณผ bash์ ๋ค๋ฅธ ์ ธ์์ ์ฌ์ฉํ ์ ์๋ ์ ธ ํ๋ ์์ํฌ๋ฅผ ์๊ฐํ๋ ๊ณณ์ ๋๋ค.
- learnyoubash๋ ์ฒซ bash ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๋ ๋ฐ ๋์์ด ๋๋ ๊ณณ์ ๋๋ค.
- shellcheck๋ ์ ธ ์คํฌ๋ฆฝํธ์ ๋ํ ์ ์ ๋ถ์ ๋๊ตฌ์ ๋๋ค. www.shellcheck.net ์นํ์ด์ง๋ก ์ฌ์ฉํ๊ฑฐ๋ ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ค์น์ ๋ํ ์์ธํ ๋ด์ฉ์ koalaman/shellcheck์์ ํ์ธํ ์ ์์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก, Stack Overflow์์ tagged as bash๋ ๋ง์ ์ง๋ฌธ์ ๋ํ ๋ต์ ์ป์ ์ ์์ผ๋ฉฐ, ๊ทธ๊ฒ์ ํตํด์ ๋ฐฐ์ธ ์ ์๋ ๊ฐ์ฅ ์ข์ ์ฅ์์ ๋๋ค.
ยฉ Denys Dovhan