
지난 글에 이어 작성하는 리눅스 기초 내용이다.
Bash의 기능이 이렇게 많은 건 처음 알았다.
심지어 조건문이나 반복문도 가능하다!
기본 명령어 이전에 이런 내용이 나오는 게 조금 아이러니하긴 하지만
일단 작성하고 나머지는 다음 편에 이어서 써보는 걸로,,
변수
변수는 데이터를 저장하는 메모리 공간
이름으로 접근하여 값을 읽고 쓸 수 있음
변수 할당 문법
변수_이름=값
공백 없이 =로 직접 할당
따옴표 없이도 가능하지만, 공백이나 특수문자가 포함되면 따옴표 사용 권장
V1=hello
echo $V1 # hello
echo ${V1} # hello
# 명령어 결과 변수에 저장 (명령어 치환)
DATE=$(date)
echo $DATE
# 2025. 11. 27. (목) 15:07:09 KST
# 변수 목록에서 특정 변수 검색
set | grep V1 # V1=hello
변수 사용
변수 값을 참조할 때는 앞에 $를 붙임
$V1 # 간단 참조 (권장하지 않음)
${V1} # 중괄호로 명확히 구분 (권장)
# 문제 상황
NAME=John
echo "Hello $NAMEworld" # Hello Johnworld (NAMEworld로 인식)
echo "Hello ${NAME}world" # Hello Johnworld (올바름)
# 배열/연결 시 필수
FILES=(file1.txt file2.txt)
echo ${FILES[0]} # file1.txt
변수의 데이터 타입
Bash에서 모든 변수는 문자열로 저장
숫자처럼 보이는 값도 내부적으로 문자열이지만, 산술 연산 시에는 자동으로 숫자로 변환되어 계산
Bash에서 변수로 산술 연산
| 방법 | 문법 | 특징 |
|---|---|---|
| $(( )) | c=$((a + b)) | 가장 빠르고 직관적, 중첩 가능 |
| let | let "c=a+b" | 따옴표 필요, 약간 오래됨 |
| expr | c=$(expr $a + $b) | 외부 명령어, 느리고 복잡 |
| bc | c=a + $b" | bc) |
산술 연산 예시
# 1) let 명령어 (기존 방식)
let "c=a+b"
let "c=a*b"
let "c=a**2" # 거듭제곱
# 2) $(( )) 산술 확장 (가장 권장)
c=$((a + b))
c=$((a * b))
c=$((a ** 2))
# 3) expr 명령어 (구 방식, 피함)
c=$(expr $a + $b)
# 4) declare -i (정수 속성 부여)
declare -i num1=10
declare -i num2=20
num1=$((num1 + num2))
echo $num1 # 30
if문의 기본 구조
if 조건
then
명령1
else
명령2
fi
# 세미콜론 사용
if 조건; then
명령1
elif 조건2; then
명령2
else
명령3
fi
if문의 조건
참/거짓 판단 기준: 종료 코드($?)
참 : 명령 실행 후 종료 코드가 0
거짓 : 종료 코드가 0이 아닌 값
username@host:~$ echo $?
0 # 이전 명령 성공
username@host:~$ cc # 컴파일 오류
cc: fatal error: no input files
username@host:~$ echo $?
1 # 실패
싱글 브래킷
Bash의 조건문에 사용하는 명령어
if [ 조건 ]
then
echo "참"
fi
더블 브래킷
Bash의 확장
if [[ 조건 ]]
then
echo "참"
fi
문자열 테스트 연산자
| 연산자 | 의미 | 예시 |
|---|---|---|
| = | 문자열 동일 | [ "B" ] |
| != | 문자열 다름 | [ "B" ] |
| -z | 빈 문자열 | [ -z "$A" ] |
| -n | 비어있지 않음 | [ -n "$A" ] |
산술 테스트 연산자
| 연산자 | 의미 | 예시 |
|---|---|---|
| -eq | equal, 같음 | [ "34" -eq "34" ]→ True |
| -ne | not equal, 다름 | [ "34" -ne "56" ]→ True |
| -le | less than or equal, 작거나 같음 | [ "34" -le "34" ]→ True |
| -lt | less than, 작음 | [ "34" -lt "56" ]→ True |
| -gt | greater than, 큼 | [ "56" -gt "34" ]→ True |
| -ge | greater than or equal, 크거나 같음 | [ "34" -ge "34" ]→ True |
#!/bin/bash
A="34"
B="34"
echo "A=$A, B=$B"
if [ "$A" -eq "$B" ]; then
echo "-eq operator: True"
fi
A="34"
B="56"
echo "A=$A, B=$B"
if [ "$A" -lt "$B" ]; then
echo "-lt operator: True"
fi
파일 테스트 연산자
| 연산자 | 의미 | 예시 |
|---|---|---|
| -e | 존재 | [ -e "file.txt" ] |
| -f | 일반 파일 | [ -f "file.txt" ] |
| -d | 디렉토리 | [ -d "/home" ] |
| -s | 크기가 0보다 큼 | [ -s "data.txt" ] |
| -L | 심볼릭 링크 | [ -L "link" ] |
| -r | 읽기 가능 | [ -r "file.txt" ] |
| -w | 쓰기 가능 | [ -w "file.txt" ] |
| -x | 실행 가능 | [ -x "script.sh" ] |
논리 테스트 연산자
| 연산자 | 의미 | 예시 |
|---|---|---|
| && | AND | [ 조건1 ] && [ 조건2 ] |
| ! | NOT | [ ! 조건 ] |
case문
다중 분기문으로 사용하면 if-elif보다 깔끔
[ ] 내부는 공백 필수 (예 : [ "$A" -eq "$B" ] )
문자열 비교 시 따옴표 필수 (예 : [ "$A" = "$B" ])
종료 코드 $?로 조건 판단
#!/bin/bash
ANIMAL="dog"
case "$ANIMAL" in
"horse" | "dog" | "cat")
LEGS="4"
;;
"human" | "chicken")
LEGS="2"
;;
*)
LEGS="?"
;;
esac
echo "$ANIMAL has $LEGS legs."
중첩 if문 실습
#!/bin/bash
# 가장 낮은 점수의 과목 출력하기
KOREAN="86"
ENGLISH="84"
MATH="76"
if [ "$KOREAN" -lt "$ENGLISH" ]
then
if [ "$KOREAN" -lt "$MATH" ]
then
echo "The lowest: Korean, Score: $KOREAN"
else
echo "The lowest: Math, Score: $MATH"
fi
else
if [ "$ENGLISH" -lt "$MATH" ]
then
echo "The lowest: English, Score: $ENGLISH"
else
echo "The lowest: Math, Score: $MATH"
fi
fi
기본 형식 for문
# 기본 형식
for 변수 in 목록
do
명령
done
# C언어 스타일 형식
for ((초기식; 조건식; 증감식))
do
명령
done
# 기본 형식 예시
#!/bin/bash
for i in 1 2 3 4 5
do
echo "number $i"
done
C언어 스타일 for문
# C언어 스타일 형식
for ((초기식; 조건식; 증감식))
do
명령
done
# C언어 스타일 예시
#!/bin/bash
for ((i = 0; i < 5; i++))
do
echo "number $i"
done
while문
조건이 참인 동안 명령을 반복해서 실행
while 조건식
do
명령
done
#!/bin/bash
i=0
while [ "$i" -lt 5 ]
do
echo "number $i"
let "i++"
done
until문
조건이 거짓인 동안 명령을 반복해서 실행
until 조건식
do
명령
done
break
반복문 완전 종료
continue
현재 반복을 건너뛰고 다음 반복 진행
함수(function)
재사용 가능한 코드 블록으로, 프로그램의 모듈화와 유지보수를 위해 필수적
Bash 함수를 사용하면 명령어 집합을 이름으로 묶어 호출할 수 있음
매개변수 전달과 반환값 처리가 가능
함수의 특징
코드 재사용성 : 반복되는 작업을 한 번만 작성
가독성 향상 : 복잡한 스크립트를 논리 단위로 분리
매개변수 지원 : $1, $2 등으로 인자 전달
반환값 : return (상태코드 0-255), echo (출력값)
함수의 선언과 사용
# 함수 선언 형식 3가지
함수_이름()
{ ... }
function 함수_이름
{ ... }
function 함수_이름()
{ ... }
매개변수 (Arguments)
함수 호출 시 전달된 값들이 위치 매개변수로 저장됨
$1, $2, $3 ... : 들어온 순서대로 인자
$# : 인자 개수
"$@" : 모든 인자 (개별 문자열 유지)
반환값 (Return Value)
return N : 상태 코드 반환 (범위는 0-255, 0이면 성공)
echo 결과값 : 표준 출력으로 값 반환 → 명령어 치환 $(함수명)
출력값
함수를 실행하며 표준 출력에 출력된 내용을 반환하는 방법
명령어 치환
달러 기호($)와 소괄호(())로 명령 또는 함수 호출을 감싸는 방법
함수 사용 예시
function 함수_이름()
{
변수_이름="$1"
...
return $반환값_이름
}
함수_이름 "값"
저장용_변수="$?"
위치 매개변수(Positional Parameters)
스크립트나 함수에 전달된 인자를 순서대로 저장하는 변수
$1, $2, $3 ... : 첫 번째, 두 번째 인자
${10}, ${11} ... : 10번째부터 중괄호 필수
특수 매개변수
| 변수 | 의미 | 예시 (./script.sh arg1 arg2) |
|---|---|---|
| $# | 매개변수 개수 | 2 |
| $0 | 실행 파일명 | ./script.sh |
| $* | 모든 인자 (하나의 문자열) | arg1 arg2 |
| $@ | 모든 인자 (각각 인식) | "arg1" "arg2" |
| $? | 최근 명령 반환값 | 0(성공),1(실패) |
| $$ | 현재 셸 PID | 12345 |
# ./test.sh a "b c" d
echo "\$* : $*" # $* : a b c d # 하나의 문자열
echo "\"\$*\" : \"$*\"" # "$*" : "a b c d" # 하나의 문자열
echo "\$@ : $@" # $@ : a b c d # 공백으로 분리
echo "\"\$@\" : \"$@\"" # "$@" : "a" "b c" "d" # 각 인자 개별 유지
makefile에서의 활용
# rule 형식
target: dependencies
command
# $* : 모든 의존성 파일을 하나의 문자열로 받음
program: file1.c file2.c file3.c
cc -o program $* # file1.c file2.c file3.c 모두 컴파일
함수 로컬 변수 (Local Variables)
함수 안에서 local 이라는 키워드와 함께 선언된 변수
함수 내부에서만 유효하며, 함수 종료 후 자동 소멸
my_function() {
local temp_var="지역변수" # local 키워드 필수
echo "$temp_var"
}
my_function # 지역변수 출력
echo "$temp_var" # 빈 문자열 (함수 밖에서는 접근 불가)
글로벌 변수(Global Variables)
스크립트 최상위 레벨에서 선언된 변수
함수 내부에서도 접근/수정 가능
함수 로컬 변수를 제외한 모든 변수
변수의 종류
셸 변수(Shell Variables)
현재 셸 세션(bash)에서만 유효한 변수
자식 프로세스(다른 bash, 스크립트)에서는 접근 불가
username@host:~$ MY_VAR="hello"
username@host:~$ set | grep MY_VAR
MY_VAR=hello # set에 표시됨
환경변수(Environment Variable)
자식 프로세스까지 상속되는 변수
부모 bash → 자식 bash → 손자 bash
username@host:~$ env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
변수 확인하기
| 명령어 | 출력 내용 | 예시 |
|---|---|---|
| set | 모든셸 변수 | set |
| env | 모든환경변수 | env |
| printenv | 특정 환경변수 | printenv PATH |
환경변수
프로세스가 실행되는 환경 정보를 저장하는 특별한 변수
프로그램은 PATH, USER, HOME 등 환경변수를 통해 시스템 상태와 사용자 설정을 인식
환경변수의 특징
상속성 : 부모 프로세스 → 자식 프로세스에 자동 전달
영속성 : 셸 세션 동안 유지 (로그아웃 시 초기화)
전역 공유 : 같은 사용자 세션의 모든 프로세스가 공유
변수의 export
export 는 셸 변수를 환경변수로 승격시켜 자식 프로세스에 상속
스크립트 파일은 셸 변수가 유효하지 않으므로, 스크립트 내에서 변수를 사용하려면 export 필요
username@host:~$ MY_VAR="hello" # 셸 변수 생성 (현재 셸만 인식)
username@host:~$ echo $MY_VAR
hello
username@host:~$
username@host:~$ bash -c 'echo $MY_VAR' # 자식 프로세스에서 접근 불가
# 빈 출력 (상속 안 됨)
username@host:~$ export MY_VAR # export로 환경변수 변환
username@host:~$ bash -c 'echo $MY_VAR' # 자식 프로세스에서 접근 가능
hello
unset
unset 은 셸 변수와 환경변수를 모두 삭제하는 명령어
변수 자체를 메모리에서 제거하며, unset VAR1 VAR2 VAR3 등으로 여러 변수를 한꺼번에 삭제 가능
$$는 시스템 변수이므로 unset 불가
PATH 환경변수
명령어 실행 시 시스템이 자동으로 검색하는 디렉토리 목록을 콜론(:)으로 구분하여 저장한 환경변수
명령어 입력 → PATH의 각 디렉토리 순차 검색 → 실행파일 발견 → 실행
username@host:~$ echo $PATH # 현재 PATH 환경변수 확인
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
username@host:~$ PATH="$HOME/bin:$PATH" # 현재 세션에 사용자 홈 디렉토리 추가
Bash 초기화 과정
Bash 실행 시 시스템 파일 → 사용자 설정 파일을 순차 로드하여 환경을 초기화
~/.bashrc 는 비로그인 셸에서 자동 로드되는 사용자 설정 파일로, 개인별 환경 설정에 주로 이용
로그인 셸 (ssh, su -)
├── /etc/profile
├── ~/.bash_profile → ~/.bash_login → ~/.profile
└── ~/.bashrc (소스됨)
비로그인 셸 (스크립트, 터미널)
└── ~/.bashrc ← 개인 설정 주로 여기에
username@host:~$ echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc # ~/.bashrc에 추가
username@host:~$ source ~/.bashrc # 즉시 적용배열은 생략
쿼팅(Quoting)
셸은 $ , * , ? , 공백, ``` 등을 특수 문자로 해석하여 치환/확장 작업을 함
이때 특수 문자들의 특별한 의미를 제거하거나 제어하는 기술
문자열이나 변수를 따옴표로 감싸서 수행됨
싱글 쿼트 ' ' (Literal Quote)
완전 리터럴로, 모든 특수 문자를 문자 그대로 유지함
다른 의미로 확장되지 않는다는 뜻
NAME="John"
echo '$USER is $NAME' # $USER is $John (변수 치환 X)
echo 'Today is $(date)' # Today is $(date) (명령어 치환 X)
echo '*' # * (와일드카드 확장 X)
더블 쿼트 " " (Partial Quote)
부분 확장으로, 변수 치환과 명령어 치환만 허용하고 와일드카드(*, ?)는 차단
변수는 ${변수} 형식으로 사용하고, 명령어 치환은 $(명령어) 또는 명령어 로 사용
내부에서 이스케이프 문자 활용 가능
NAME="John"
echo "$USER is $NAME" # username is John (변수 치환 O)
echo "$(date)" / echo "`date`" # Mon Dec 1 08:39:01 UTC 2025 (명령어 치환 O)
echo "*" # * (와일드카드 확장 X)
이스케이프 문자 \ (Escape Character)
특정 문자만 이스케이프하여 특수한 의미를 제거할 때 사용할 수 있음
이스케이프 문자 뒤에 개행 문자를 입력하면 여러 줄에 걸쳐 하나의 명령 입력 가능
echo "Name: \$NAME" # Name: $NAME (\로 $ 보호)
echo "Path: /home/user/*" # Path: /home/user/* (* 보호)
echo "Hello\tWorld" # Hello World (\t 탭 문자)
echo "Hello\
> World" # HelloWorld (명령어 이어서 입력)
파도 파도 끝이 없는 리눅스의 세계를 느끼고 있다.
아직 make 같은 내용은 나오지도 않았는데 내용이 참 많다,,!