1. 환경 변수 기초

환경 변수 vs 쉘 변수

# 쉘 변수: 현재 쉘에서만 유효 (자식 프로세스에 전달되지 않음)
MY_VAR="hello"
echo $MY_VAR       # hello
 
# 환경 변수: 자식 프로세스에도 상속됨
export MY_VAR="hello"
# 또는
export MY_VAR      # 이미 존재하는 쉘 변수를 환경 변수로 승격

환경 변수 조회

# 모든 환경 변수 출력
env
# 또는
printenv
 
# 특정 변수만 출력
printenv PATH
echo $PATH
 
# 환경 변수 + 쉘 변수 + 쉘 함수 모두 출력
set
 
# 환경 변수만 (set에서 필터링)
env | sort

환경 변수 설정/삭제

# 설정 (현재 쉘 + 자식 프로세스)
export JAVA_HOME="/usr/lib/jvm/java-17"
 
# 특정 명령에만 적용 (일회성)
LANG=C sort file.txt
# 또는
env LANG=C sort file.txt
 
# 삭제
unset MY_VAR
 
# 모든 환경 변수 제거 후 깨끗한 상태로 명령 실행
env -i /bin/bash

2. 주요 환경 변수

변수설명예시
PATH실행 파일 검색 경로/usr/local/bin:/usr/bin:/bin
HOME현재 사용자 홈 디렉토리/home/phh
USER현재 사용자 이름phh
SHELL현재 사용자의 기본 쉘/bin/bash
LANG기본 로케일ko_KR.UTF-8
LC_ALL모든 로케일 강제 지정 (LANG보다 우선)C.UTF-8
TERM터미널 타입xterm-256color
EDITOR기본 텍스트 에디터vim
VISUAL비주얼 에디터 (EDITOR보다 우선)vim
LD_LIBRARY_PATH동적 라이브러리 검색 경로/usr/local/lib
DISPLAYX11 디스플레이 서버:0
PWD현재 작업 디렉토리/home/phh/project
OLDPWD이전 작업 디렉토리/home/phh
HOSTNAME호스트 이름myserver
LOGNAME로그인 이름phh
HISTSIZE메모리에 저장할 히스토리 수1000
HISTFILESIZE히스토리 파일에 저장할 수2000

XDG 디렉토리 변수

freedesktop.org 표준으로 사용자 디렉토리를 정의한다.

# 기본값 (미설정 시 자동 적용)
XDG_CONFIG_HOME="$HOME/.config"      # 설정 파일
XDG_DATA_HOME="$HOME/.local/share"   # 애플리케이션 데이터
XDG_CACHE_HOME="$HOME/.cache"        # 캐시
XDG_STATE_HOME="$HOME/.local/state"  # 상태 데이터 (로그, 히스토리)
XDG_RUNTIME_DIR="/run/user/$UID"     # 런타임 파일 (소켓, PID 등)
 
# 시스템 레벨
XDG_DATA_DIRS="/usr/local/share:/usr/share"
XDG_CONFIG_DIRS="/etc/xdg"

3. PATH 관리

PATH 추가

# 끝에 추가 (기존 명령보다 낮은 우선순위)
export PATH="$PATH:/opt/myapp/bin"
 
# 앞에 추가 (기존 명령보다 높은 우선순위)
export PATH="/opt/myapp/bin:$PATH"
 
# 확인
echo $PATH
which python3     # 어떤 경로의 python3이 실행되는지

PATH 순서의 의미

# PATH="/usr/local/bin:/usr/bin:/bin"일 때:
# 명령어를 입력하면 왼쪽 디렉토리부터 순서대로 검색
# 같은 이름의 명령이 여러 경로에 있으면 먼저 발견된 것이 실행됨
 
# 예: python3이 여러 곳에 있을 때
# /usr/local/bin/python3  ← 이것이 실행됨 (PATH에서 먼저)
# /usr/bin/python3
 
# 모든 경로 확인
which -a python3
type -a python3

보안 주의사항: 현재 디렉토리(.) 포함 금지

# 절대 이렇게 하면 안 됨!
export PATH=".:$PATH"     # 위험!
export PATH="$PATH:."     # 위험!
 
# 이유:
# 공격자가 /tmp에 ls라는 악성 스크립트를 만들어 놓으면
# 사용자가 /tmp에서 ls를 실행할 때 악성 스크립트가 실행됨
# → 항상 절대 경로나 PATH에 등록된 경로만 사용
 
# 현재 디렉토리의 스크립트 실행 시
./myscript.sh    # 명시적으로 ./를 붙여야 함

4. 쉘 설정 파일 로딩 순서

로그인 쉘 (Login Shell)

SSH 접속, su -, 콘솔 로그인 시 실행.

관례: ~/.bash_profile에서 ~/.bashrc를 source하여 양쪽 모두 적용되게 한다.

# ~/.bash_profile 일반적인 내용
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi
 
# 로그인 쉘 전용 설정 (환경 변수 등)
export JAVA_HOME="/usr/lib/jvm/java-17"
export PATH="$JAVA_HOME/bin:$PATH"

비로그인 쉘 (Non-Login Shell)

터미널 에뮬레이터(GNOME Terminal 등)에서 새 탭/창 열 때, bash 명령 실행 시.

시스템 전역: /etc/bash.bashrc
                │
                ▼
사용자별: ~/.bashrc
# ~/.bashrc 일반적인 내용
# alias 설정
alias ll='ls -alF'
alias la='ls -A'
alias grep='grep --color=auto'
 
# 프롬프트 설정
PS1='\[\e[32m\]\u@\h\[\e[0m\]:\[\e[34m\]\w\[\e[0m\]\$ '
 
# 쉘 옵션
shopt -s histappend
shopt -s checkwinsize

로그아웃 시

# 로그인 쉘 종료 시 실행
~/.bash_logout

정리: 설정 파일 용도 가이드

설정 종류어디에 넣을지이유
환경 변수 (PATH, JAVA_HOME 등)~/.bash_profile 또는 ~/.profile로그인 시 한 번만 설정하면 됨
alias, 쉘 옵션, 프롬프트~/.bashrc모든 쉘에서 필요
시스템 전역 설정/etc/profile.d/custom.sh모든 사용자에게 적용

5. alias

alias 설정 및 관리

# alias 확인
alias            # 모든 alias 표시
alias ll         # 특정 alias 확인
type ll          # 명령어 타입 확인 (alias, builtin, file 등)
 
# alias 설정 (현재 세션)
alias ll='ls -alF'
alias gs='git status'
alias dc='docker compose'
alias ..='cd ..'
alias ...='cd ../..'
 
# 복잡한 alias
alias myip='curl -s ifconfig.me'
alias ports='ss -tulanp'
alias update='sudo apt update && sudo apt upgrade -y'
 
# alias 삭제
unalias ll
 
# 모든 alias 삭제
unalias -a
 
# alias를 무시하고 원래 명령 실행
\ls          # 백슬래시
command ls   # command 내장 명령
/bin/ls      # 절대 경로

영구 alias 설정

# ~/.bashrc에 추가
echo "alias ll='ls -alF'" >> ~/.bashrc
 
# 변경사항 즉시 적용
source ~/.bashrc
# 또는
. ~/.bashrc

6. 쉘 옵션

shopt - Bash 전용 옵션

# 모든 옵션 상태 확인
shopt
 
# 특정 옵션 상태 확인
shopt -s cdspell       # 활성화 (-s: set)
shopt -u cdspell       # 비활성화 (-u: unset)
 
# 유용한 shopt 옵션
shopt -s cdspell       # cd 오타 자동 교정 (cd /hme → /home)
shopt -s dirspell      # 디렉토리 이름 탭 완성 시 오타 교정
shopt -s histappend    # 히스토리 덮어쓰기 대신 추가 (여러 터미널 사용 시 중요)
shopt -s checkwinsize  # 터미널 크기 변경 시 자동 업데이트
shopt -s globstar      # ** 재귀 glob 활성화 (ls **/*.py)
shopt -s nocaseglob    # glob 패턴에서 대소문자 무시
shopt -s dotglob       # glob에 숨김파일(.) 포함

set - POSIX 쉘 옵션

# 주요 옵션
set -e    # 명령 실패 시 즉시 종료 (스크립트에서 유용)
set -u    # 미정의 변수 사용 시 에러 (set -o nounset)
set -x    # 실행되는 명령 출력 (디버깅) (set -o xtrace)
set -o pipefail  # 파이프라인 중 하나라도 실패하면 실패
 
# 스크립트 시작 시 권장 설정
set -euo pipefail
 
# 해제
set +e    # -e 해제
set +x    # -x 해제
 
# 모든 옵션 확인
set -o

7. 로케일 설정

현재 로케일 확인

locale
# LANG=ko_KR.UTF-8
# LC_CTYPE="ko_KR.UTF-8"
# LC_NUMERIC="ko_KR.UTF-8"
# LC_TIME="ko_KR.UTF-8"
# LC_COLLATE="ko_KR.UTF-8"
# ... (모든 LC_* 변수)
# LC_ALL=
 
# 사용 가능한 로케일 목록
locale -a

LANG vs LC_* vs LC_ALL

우선순위: LC_ALL > LC_* (개별) > LANG

LANG         - 기본 로케일 (모든 LC_*의 기본값)
LC_CTYPE     - 문자 분류 (대소문자, 멀티바이트 등)
LC_NUMERIC   - 숫자 표기법 (소수점, 천단위 구분자)
LC_TIME      - 시간/날짜 표기법
LC_COLLATE   - 문자열 정렬 순서
LC_MESSAGES  - 시스템 메시지 언어
LC_ALL       - 모든 LC_*를 강제 설정 (최우선)
# 시스템 기본 로케일 설정
sudo localectl set-locale LANG=ko_KR.UTF-8
 
# 로케일 생성
sudo locale-gen ko_KR.UTF-8
sudo dpkg-reconfigure locales    # Debian 계열 대화형 설정
 
# 정렬 문제 해결 (C 로케일 사용)
# 한글/특수문자 정렬이 예상과 다를 때:
export LC_COLLATE=C
# C 로케일: 바이트 값 기준 정렬 (ASCII 순서)

8. 시간대 설정

timedatectl (systemd)

# 현재 시간대 확인
timedatectl
#                Local time: Fri 2024-01-15 14:30:00 KST
#            Universal time: Fri 2024-01-15 05:30:00 UTC
#                  RTC time: Fri 2024-01-15 05:30:00
#                 Time zone: Asia/Seoul (KST, +0900)
 
# 시간대 목록 조회
timedatectl list-timezones
timedatectl list-timezones | grep Seoul
 
# 시간대 변경
sudo timedatectl set-timezone Asia/Seoul
 
# NTP 동기화 활성화
sudo timedatectl set-ntp true

수동 설정

# 심볼릭 링크 방식
sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
 
# 또는 tzdata 재설정
sudo dpkg-reconfigure tzdata    # Debian 계열
 
# TZ 환경 변수로 일시적 변경
TZ='America/New_York' date
TZ='UTC' date

9. 커널 파라미터

sysctl - 런타임 커널 파라미터 조회/변경

# 모든 파라미터 조회
sysctl -a
 
# 특정 파라미터 조회
sysctl net.ipv4.ip_forward
sysctl vm.swappiness
 
# 임시 변경 (재부팅 시 초기화)
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w vm.swappiness=10
 
# /proc/sys/를 통해 직접 조회/변경
cat /proc/sys/net/ipv4/ip_forward
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

영구 설정

# /etc/sysctl.conf 또는 /etc/sysctl.d/*.conf 에 추가
# 예: /etc/sysctl.d/99-custom.conf
 
net.ipv4.ip_forward = 1
vm.swappiness = 10
net.core.somaxconn = 65535
fs.file-max = 2097152
net.ipv4.tcp_max_syn_backlog = 65535
 
# 적용
sudo sysctl -p                     # /etc/sysctl.conf 적용
sudo sysctl -p /etc/sysctl.d/99-custom.conf   # 특정 파일 적용
sudo sysctl --system               # 모든 설정 파일 적용

주요 커널 파라미터

파라미터설명기본값
net.ipv4.ip_forwardIP 포워딩 (라우터 역할)0
vm.swappinessswap 사용 적극성60
fs.file-max시스템 전체 최대 파일 핸들 수~100000
net.core.somaxconn소켓 listen 백로그 최대값4096
net.ipv4.tcp_max_syn_backlogSYN 대기 큐 크기128~1024
kernel.pid_max최대 PID 값32768
vm.overcommit_memory메모리 오버커밋 정책 (0/1/2)0

10. 리소스 제한

ulimit - 현재 세션 리소스 제한

# 모든 제한 확인
ulimit -a
 
# soft limit 확인/설정 (일반 사용자가 변경 가능, hard 이하)
ulimit -n        # 오픈 파일 수 확인 (soft)
ulimit -n 65535  # 변경
 
# hard limit 확인 (root만 변경 가능)
ulimit -Hn       # 오픈 파일 수 hard limit
 
# 주요 옵션
ulimit -n    # 오픈 파일 수 (nofile)
ulimit -u    # 사용자 프로세스 수 (nproc)
ulimit -f    # 파일 크기 (blocks)
ulimit -v    # 가상 메모리 크기 (kbytes)
ulimit -c    # 코어 덤프 크기 (blocks, 0=비활성화)
ulimit -s    # 스택 크기 (kbytes)

/etc/security/limits.conf - 영구 설정

# 형식: <domain> <type> <item> <value>
# domain: 사용자명, @그룹명, * (모든 사용자)
# type: soft, hard, - (양쪽 모두)
# item: nofile, nproc, memlock 등
 
# 예시:
*               soft    nofile          65535
*               hard    nofile          65535
*               soft    nproc           65535
*               hard    nproc           65535
@developers     soft    nofile          100000
@developers     hard    nofile          100000
www-data        soft    nofile          100000
www-data        hard    nofile          100000
 
# systemd 서비스의 경우 limits.conf 대신 유닛 파일에서 설정
# [Service]
# LimitNOFILE=65535
# LimitNPROC=65535

/etc/security/limits.d/

# limits.conf보다 우선적으로 적용되는 추가 설정
# 예: /etc/security/limits.d/99-custom.conf

11. alternatives 시스템

같은 기능을 하는 여러 프로그램 중 기본 사용할 것을 관리하는 시스템.

update-alternatives (Debian/Ubuntu)

# 현재 설정 확인
sudo update-alternatives --display java
sudo update-alternatives --display editor
 
# 대화형으로 선택
sudo update-alternatives --config java
# Selection    Path                                      Priority
# --------------------------------------------------------
# * 0          /usr/lib/jvm/java-17-openjdk-amd64/bin/java  1711
#   1          /usr/lib/jvm/java-11-openjdk-amd64/bin/java  1111
#   2          /usr/lib/jvm/java-17-openjdk-amd64/bin/java  1711
 
# 수동 설정
sudo update-alternatives --set java /usr/lib/jvm/java-11-openjdk-amd64/bin/java
 
# 새 대안 등록
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.11 2
# 형식: --install <링크> <이름> <경로> <우선순위>
 
# 대안 제거
sudo update-alternatives --remove python /usr/bin/python3.10
 
# 모든 alternatives 목록
sudo update-alternatives --get-selections

alternatives (RHEL/CentOS)

# RHEL 계열도 동일한 명령 사용 가능
alternatives --config java
alternatives --display java

활용 예시

# Python 버전 관리
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 2
sudo update-alternatives --config python3
 
# Java 버전 관리
sudo update-alternatives --config java
sudo update-alternatives --config javac
 
# 기본 에디터 변경
sudo update-alternatives --config editor
# 또는 환경 변수로
export EDITOR=vim
export VISUAL=vim

실전 정리: 새 서버 초기 환경 설정 체크리스트

# 1. 시간대 설정
sudo timedatectl set-timezone Asia/Seoul
 
# 2. 로케일 설정
sudo localectl set-locale LANG=ko_KR.UTF-8
 
# 3. 호스트네임 설정
sudo hostnamectl set-hostname myserver
 
# 4. 커널 파라미터 조정
cat << 'EOF' | sudo tee /etc/sysctl.d/99-custom.conf
net.core.somaxconn = 65535
fs.file-max = 2097152
vm.swappiness = 10
EOF
sudo sysctl --system
 
# 5. 리소스 제한 설정
cat << 'EOF' | sudo tee /etc/security/limits.d/99-custom.conf
*  soft  nofile  65535
*  hard  nofile  65535
*  soft  nproc   65535
*  hard  nproc   65535
EOF
 
# 6. 쉘 환경 설정 (~/.bashrc)
cat << 'EOF' >> ~/.bashrc
# Custom aliases
alias ll='ls -alF --color=auto'
alias grep='grep --color=auto'
 
# History settings
export HISTSIZE=10000
export HISTFILESIZE=20000
export HISTTIMEFORMAT="%F %T "
shopt -s histappend
 
# Default editor
export EDITOR=vim
export VISUAL=vim
EOF
source ~/.bashrc