๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
6. CS ๊ธฐ์ดˆ ๐Ÿ“š/Linux & Unix ๐Ÿง

[Linux/Unix][3-4] bash ํŒŒ์ผ / ๋งค๊ฐœ๋ณ€์ˆ˜ ํ™•์žฅ ๋ฌธ๋ฒ• / ${:-}, ${:=}, ${:+}, ${:?}

by lxvxxu 2025. 10. 21.

 

๊ฐ™์ด ๋ณด๋ฉด ์ข‹์€ ๊ธ€

2025.10.21 - [5. Computer Science Basics ๐Ÿงฑ/Linux & Unix ๐Ÿง] - [Linux/Unix] 03-1. bash metacharacter (*, ?, $, &)/echo ๋ช…๋ น์–ด/Bash C printf() ๋ฌธ๋ฒ•

 

[Linux/Unix] 03-1. bash metacharacter (*, ?, $, &)/echo ๋ช…๋ น์–ด/Bash C printf() ๋ฌธ๋ฒ•

๐Ÿงญ Bash ๋ฉ”ํƒ€๋ฌธ์ž (Metacharacter)๋ฉ”ํƒ€๋ฌธ์ž(Metacharacter)๋Š” Bash์—์„œ ํŠน๋ณ„ํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š” ๊ธฐํ˜ธ๋ฅผ ๋งํ•œ๋‹ค.ํŒŒ์ผ๋ช… ํ™•์žฅ(globbing), ๋ช…๋ น ์‹คํ–‰, ๋ณ€์ˆ˜ ์น˜ํ™˜, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ฒ˜๋ฆฌ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.๐ŸŒŸ 1) * (

lxvxxu.tistory.com

 

๐Ÿงฉ 1๏ธโƒฃ .sh ํŒŒ์ผ์ด๋ž€?

.sh ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง„ ํŒŒ์ผ์€ Bash Shell Script (์…ธ ์Šคํฌ๋ฆฝํŠธ) ํŒŒ์ผ์ด์—์š”.
์ฆ‰, Bash ๋ช…๋ น์–ด๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ์ ์–ด ๋†“์€ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ํ…์ŠคํŠธ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

๐Ÿ“˜ ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด

  • ์šฐ๋ฆฌ๊ฐ€ ํ„ฐ๋ฏธ๋„์—์„œ ํ•˜๋‚˜์”ฉ ์ž…๋ ฅํ•˜๋Š” ๋ช…๋ น(echo, ls, cd, chmod, if, for ๋“ฑ)์„
    ํŒŒ์ผ๋กœ ์ €์žฅํ•ด๋†“๊ณ ,
    “ํ•œ ๋ฒˆ์— ์‹คํ–‰”ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“  ์ž๋™ ์‹คํ–‰ ๋ช…๋ น์„œ์˜ˆ์š”.

 

๐Ÿง  ์‹คํ–‰ ๋ฐฉ๋ฒ• (2๊ฐ€์ง€)

๋ฐฉ๋ฒ• 1๏ธโƒฃ: ์ง์ ‘ ์‹คํ–‰ (์‹คํ–‰ ๊ถŒํ•œ ํ•„์š”)

chmod +x hello.sh      # ์‹คํ–‰ ๊ถŒํ•œ ์ถ”๊ฐ€
./hello.sh             # ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ์‹คํ–‰

๋ฐฉ๋ฒ• 2๏ธโƒฃ: ํ•ด์„๊ธฐ(bash)๋ฅผ ์ง์ ‘ ์ง€์ •

bash hello.sh

๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ์‹คํ–‰ ๊ถŒํ•œ์ด ์—†์–ด๋„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ,
ํŒŒ์ผ์„ ํ•ญ์ƒ Bash๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•จ.

 

โš™๏ธ  ์ฒซ ์ค„์˜ #!/bin/bash ์˜๋ฏธ

์ด ์ค„์€ Shebang(์‰๋ฑ…) ๋˜๋Š” Hashbang ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
“์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์–ด๋–ค ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š”์ง€”๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์ด์—์š”.


๐Ÿ” ๊ตฌ์กฐ

 
#! [์ธํ„ฐํ”„๋ฆฌํ„ฐ์˜ ๊ฒฝ๋กœ]

์˜ˆ๋ฅผ ๋“ค์–ด:

์‰๋ฑ…์˜๋ฏธ
#!/bin/bash Bash๋กœ ์‹คํ–‰ (๋ฆฌ๋ˆ…์Šค ๊ธฐ๋ณธ)
#!/bin/sh ๊ธฐ๋ณธ ์‹œ์Šคํ…œ ์…ธ๋กœ ์‹คํ–‰ (์ผ๋ฐ˜ํ™”๋œ ์…ธ)
#!/usr/bin/python3 Python3๋กœ ์‹คํ–‰
#!/usr/bin/env node Node.js๋กœ ์‹คํ–‰
#!/usr/bin/env bash ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ bash๋ฅผ ์ฐพ์•„ ์‹คํ–‰ (์ด์‹์„ฑ ๋†’์Œ)

๐Ÿ’ก ๋™์ž‘ ๋ฐฉ์‹

์‰˜์ด ํŒŒ์ผ์„ ์‹คํ–‰ํ•  ๋•Œ:

  1. ์ฒซ ์ค„์ด #! ๋กœ ์‹œ์ž‘ํ•˜๋ฉด,
    ๋’ค์— ์žˆ๋Š” ๊ฒฝ๋กœ(/bin/bash)์˜ ํ”„๋กœ๊ทธ๋žจ์ด ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ•ด์„ํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฆ‰, OS๊ฐ€ ์ž๋™์œผ๋กœ “์ด๊ฑด Bash๋กœ ๋Œ๋ ค์•ผ ํ•˜๋Š”๊ตฌ๋‚˜”๋ผ๊ณ  ์ธ์‹ํ•˜๊ฒŒ ๋จ.

๐Ÿง  ์˜ˆ์‹œ ๋น„๊ต

์Šคํฌ๋ฆฝํŠธ ๋‚ด์šฉ์‹คํ–‰ ๊ฒฐ๊ณผ
#!/bin/bash
echo hello
Bash์—์„œ ์‹คํ–‰๋จ
#!/usr/bin/python3
print("hello")
Python์œผ๋กœ ์‹คํ–‰๋จ
(์‰๋ฑ… ์—†์Œ)
echo hello
ํ˜„์žฌ ๋กœ๊ทธ์ธ๋œ ์‰˜(Bash, zsh ๋“ฑ) ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์‹คํ–‰๋จ

๐Ÿšซ 3๏ธโƒฃ “๊ทธ๋Ÿผ #!/bin/bash ๋Š” ๊ผญ ์จ์•ผ ํ•ด?”

โŒ ๋ฐ˜๋“œ์‹œ ์จ์•ผ ํ•˜๋Š” ๊ฑด ์•„๋‹˜,

ํ•˜์ง€๋งŒ **“์ถ”์ฒœ” ๋˜๋Š” “์‚ฌ์‹ค์ƒ ํ‘œ์ค€”**์ด์—์š”.

์ƒํ™ฉ์‰๋ฑ… ํ•„์š” ์—ฌ๋ถ€์ด์œ 
bash script.sh ๋กœ ์ง์ ‘ ์‹คํ–‰ โŒ ์—†์–ด๋„ ๋จ (bash๋กœ ์ด๋ฏธ ์‹คํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ)  
./script.sh ๋กœ ์ง์ ‘ ์‹คํ–‰ โœ… ํ•„์š”ํ•จ (OS๊ฐ€ ์–ด๋–ค ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋กœ ๋Œ๋ฆด์ง€ ์•Œ์•„์•ผ ํ•จ)  
๋‹ค๋ฅธ ์‹œ์Šคํ…œ์—์„œ๋„ ์‹คํ–‰ํ•  ์˜ˆ์ • โœ… ํ•„์š”ํ•จ (์ด์‹์„ฑ↑, ๋ช…ํ™•์„ฑ↑)  

๐Ÿ’ก ๊ฒฐ๋ก :

๋‹จ์ˆœ ์‹ค์Šต์ด๋ผ๋ฉด ์—†์–ด๋„ ๋˜์ง€๋งŒ,
์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์Šคํฌ๋ฆฝํŠธ๋กœ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ฐฐํฌํ•  ๋•Œ๋Š” ๋ฐ˜๋“œ์‹œ ๋„ฃ๋Š” ๊ฒŒ ํ‘œ์ค€์ด์—์š”.

 


#!/bin/bash

var=defined
echo $var
echo ${var:-default}
echo ${var1:-default}
echo $var1
echo ${var1:=string}
echo $var1
echo ${var:+new}

 

 

๐Ÿงฉ ์ฝ”๋“œ ์ƒ์„ธ ํ•ด์„

์ด ์ฝ”๋“œ๋Š” Bash์˜ “๋งค๊ฐœ๋ณ€์ˆ˜ ํ™•์žฅ(Parameter Expansion)” ๋ฌธ๋ฒ•์„ ์‹คํ—˜ํ•˜๋Š” ์˜ˆ์‹œ์˜ˆ์š”.
:-, :=, :+ ๋“ฑ์˜ ์—ฐ์‚ฐ์ž๋Š” ๋ณ€์ˆ˜๊ฐ€ ์ •์˜๋˜์–ด ์žˆ๋Š”์ง€, ๋น„์–ด์žˆ๋Š”์ง€์— ๋”ฐ๋ผ
๋Œ€์ฒด๊ฐ’(default value) ์„ ์ถœ๋ ฅํ•˜๊ฑฐ๋‚˜ ํ• ๋‹น(assign) ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿง  1๏ธโƒฃ var=defined

  • ๋ณ€์ˆ˜ var ์— ๋ฌธ์ž์—ด "defined" ๋ฅผ ํ• ๋‹น.
  • ์ฆ‰, var์€ “์ •์˜๋˜์–ด ์žˆ์Œ(set)” ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

๐Ÿงพ 2๏ธโƒฃ echo $var

 
defined
  • $var → ๋ณ€์ˆ˜ var์˜ ๊ฐ’ ์ถœ๋ ฅ.
  • ๊ฒฐ๊ณผ: defined

๐Ÿงพ 3๏ธโƒฃ echo ${var:-default}

 
defined
  • ${var:-default} → var์ด ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉด ๊ทธ ๊ฐ’์„,
    ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š๊ฑฐ๋‚˜ ๋นˆ ๊ฐ’์ด๋ฉด(default) default๋ฅผ ์ถœ๋ ฅ.
  • ํ˜„์žฌ var="defined" → ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, ๊ธฐ์กด ๊ฐ’ ์ถœ๋ ฅ.

โœ… ๊ฒฐ๊ณผ: defined


๐Ÿงพ 4๏ธโƒฃ echo ${var1:-default}

 
default
  • ${var1:-default} → var1์ด ์ •์˜๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ null์ผ ๊ฒฝ์šฐ
    ์ž„์‹œ๋กœ(default) default๋ฅผ ์ถœ๋ ฅ.
  • ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ var1์—๋Š” ์•„๋ฌด ๊ฐ’๋„ ์ €์žฅ๋˜์ง€ ์•Š์Œ.
    (์ด๊ฑด ๋‹จ์ˆœํžˆ ์ถœ๋ ฅ๋งŒ ๋ฐ”๊พผ ๊ฒƒ)

โœ… ๊ฒฐ๊ณผ: default


๐Ÿงพ 5๏ธโƒฃ echo $var1

 
 
  • var1์€ ์•„์ง๋„ ์ •์˜๋˜์ง€ ์•Š์Œ(undefined) → ์ถœ๋ ฅ ์—†์Œ (๋นˆ ์ค„)

โœ… ๊ฒฐ๊ณผ: (์•„๋ฌด๊ฒƒ๋„ ์ถœ๋ ฅ๋˜์ง€ ์•Š์Œ)


๐Ÿงพ 6๏ธโƒฃ echo ${var1:=string}

 
string
  • ${var1:=string} → var1์ด ์ •์˜๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ null์ด๋ฉด,
    string์„ ์‹ค์ œ๋กœ ๋ณ€์ˆ˜์— ํ• ๋‹น(assign) ํ•˜๊ณ  ์ถœ๋ ฅํ•จ.
  • ์ด์ œ var1์€ "string" ๊ฐ’์„ ๊ฐ€์ง€๊ฒŒ ๋จ.

โœ… ๊ฒฐ๊ณผ: string


๐Ÿงพ 7๏ธโƒฃ echo $var1

 
string
  • ์œ„ ๋‹จ๊ณ„์—์„œ var1="string"์œผ๋กœ ์‹ค์ œ๋กœ ์ €์žฅ๋จ.
  • ๋”ฐ๋ผ์„œ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” string

โœ… ๊ฒฐ๊ณผ: string


๐Ÿงพ 8๏ธโƒฃ echo ${var:+new}

 
new
  • ${var:+new} → var์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค๋ฉด new๋ฅผ ์ถœ๋ ฅ.
    (๊ฐ’์ด ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์ถœ๋ ฅ ์•ˆ ํ•จ)
  • ํ˜„์žฌ var="defined" → ์กด์žฌํ•˜๋ฏ€๋กœ "new" ์ถœ๋ ฅ.
    ๋‹จ, ์‹ค์ œ ๋ณ€์ˆ˜์˜ ๊ฐ’(var)์€ ๋ฐ”๋€Œ์ง€ ์•Š์Œ.

โœ… ๊ฒฐ๊ณผ: new


๐Ÿงฎ ์ตœ์ข… ์‹คํ–‰ ๊ฒฐ๊ณผ ์ •๋ฆฌ

์ฝ”๋“œ ์ค„์ถœ๋ ฅ ๊ฒฐ๊ณผ์„ค๋ช…
echo $var defined ๊ธฐ์กด ๋ณ€์ˆ˜ ๊ฐ’
echo ${var:-default} defined var์ด ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅ
echo ${var1:-default} default var1์ด ์ •์˜๋˜์ง€ ์•Š์•„ ์ž„์‹œ๋กœ ๊ธฐ๋ณธ๊ฐ’ ํ‘œ์‹œ
echo $var1 (๋นˆ ์ค„) var1์€ ์—ฌ์ „ํžˆ ์ •์˜๋˜์ง€ ์•Š์Œ
echo ${var1:=string} string var1์— “string”์ด ์‹ค์ œ๋กœ ์ €์žฅ๋จ
echo $var1 string var1์˜ ๊ฐ’ ํ™•์ธ
echo ${var:+new} new var์ด ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ “new” ์ถœ๋ ฅ (๊ฐ’ ๋ณ€๊ฒฝ ์—†์Œ)

๐Ÿ’ก ํ•ต์‹ฌ ์ •๋ฆฌ — Bash ๋งค๊ฐœ๋ณ€์ˆ˜ ํ™•์žฅ ๋ฌธ๋ฒ•

๊ตฌ๋ฌธ์˜๋ฏธ์˜ˆ์‹œ๊ฒฐ๊ณผ
${var:-word} var์ด unset/null์ด๋ฉด word ์ถœ๋ ฅ ${name:-guest} name ์—†์œผ๋ฉด “guest”
${var:=word} var์ด unset/null์ด๋ฉด word๋ฅผ ๋Œ€์ž…ํ•˜๊ณ  ์ถœ๋ ฅ ${file:=readme.txt} file์— “readme.txt” ์ €์žฅ
${var:+word} var์ด set์ด๋ฉด word ์ถœ๋ ฅ, unset์ด๋ฉด ๋นˆ ๋ฌธ์ž์—ด ${user:+logged-in} user ์žˆ์œผ๋ฉด “logged-in”
${var:?message} var์ด unset/null์ด๋ฉด ์—๋Ÿฌ ์ถœ๋ ฅ ํ›„ ์ข…๋ฃŒ ${id:?need id} id ์—†์œผ๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ

 

 

#!/bin/bash

echo "8๏ธโƒฃ \${unsetVar:?Error: unsetVar is not defined!} :"
echo ${unsetVar:?Error: unsetVar is not defined!}

echo "์ด ์ค„์€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค (์œ„์—์„œ ์ข…๋ฃŒ๋จ)"

unsetVar๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์—๋Ÿฌ ์ถœ๋ ฅ ํ›„ ์Šคํฌ๋ฆฝํŠธ ์ข…๋ฃŒ, ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ

 

์‹คํ–‰ ๊ฒฐ๊ณผ :

8๏ธโƒฃ ${unsetVar:?Error: unsetVar is not defined!} :
bash: line 22: unsetVar: Error: unsetVar is not defined

 

โŒ ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์Šคํฌ๋ฆฝํŠธ๋Š” ์ฆ‰์‹œ ์ข…๋ฃŒ๋˜๋ฏ€๋กœ,
"์ด ์ค„์€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค" ๋Š” ์ถœ๋ ฅ๋˜์ง€ ์•Š์Œ.

 

์ถ”๊ฐ€ ์˜ˆ์‹œ :

#!/bin/bash
echo ${HOME:?Home directory not found!}
echo ${PATH:?PATH variable is missing!}
echo ${MYVAR:?Custom variable is missing!}

 

โœ… ๊ฒฐ๊ณผ

  • HOME, PATH๋Š” ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ •์ƒ ํ†ต๊ณผ
  • MYVAR๋Š” ์—†์œผ๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์—๋Ÿฌ ํ›„ ์ข…๋ฃŒ:
bash: line 3: MYVAR: Custom variable is missing!

โœ… ํ•œ ์ค„ ์š”์•ฝ

์ด ์ฝ”๋“œ๋Š” Bash์—์„œ ๋ณ€์ˆ˜์˜ “์ •์˜ ์—ฌ๋ถ€”์— ๋”ฐ๋ผ
๊ธฐ๋ณธ๊ฐ’(:-), ๋Œ€์ž…(:=), ์กด์žฌ ์‹œ ์น˜ํ™˜(:+)์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€๋ฅผ
์ˆœ์„œ๋Œ€๋กœ ์‹คํ—˜ํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.