기본 탐색

ls - 디렉토리 내용 나열

ls              # 현재 디렉토리 내용
ls /path/to/dir # 지정 디렉토리 내용

주요 옵션:

옵션설명예시
-l긴 형식(상세 정보)ls -l
-a숨김 파일(.으로 시작) 포함ls -a
-la숨김 파일 포함 상세 목록ls -la
-lh사람이 읽기 좋은 크기 표시 (K, M, G)ls -lh
-R재귀적으로 하위 디렉토리 포함ls -R
-t수정 시간순 정렬 (최신 먼저)ls -lt
-S파일 크기순 정렬 (큰 것 먼저)ls -lS
-r정렬 순서 반전ls -ltr (오래된 순)
-iinode 번호 표시ls -li
-d디렉토리 자체 정보 (내용 X)ls -ld /etc
-1한 줄에 하나씩 출력ls -1
--color색상으로 파일 타입 구분ls --color=auto
# ls -l 출력 해석
# -rw-r--r-- 1 user group 4096 Jan 15 10:30 file.txt
# │          │  │    │     │    │            └─ 파일명
# │          │  │    │     │    └─ 수정 시간
# │          │  │    │     └─ 파일 크기(바이트)
# │          │  │    └─ 소유 그룹
# │          │  └─ 소유 사용자
# │          └─ 하드 링크 수
# └─ 파일 타입 + 권한
 
# 가장 큰 파일 10개
ls -lhS /var/log/ | head -10
 
# 최근 수정된 파일 확인
ls -lt /etc/ | head -20

cd - 디렉토리 이동

cd /path/to/dir   # 절대 경로로 이동
cd subdir         # 상대 경로로 이동
cd ~              # 홈 디렉토리
cd                # 홈 디렉토리 (동일)
cd -              # 이전 디렉토리로 돌아가기
cd ..             # 부모 디렉토리
cd ../..          # 두 단계 상위

pwd - 현재 디렉토리 출력

pwd               # 현재 작업 디렉토리 경로
pwd -P            # 심볼릭 링크 해석하여 실제 경로 출력
pwd -L            # 심볼릭 링크를 그대로 출력 (기본값)

tree - 디렉토리 트리 구조 표시

tree              # 현재 디렉토리 트리
tree -L 2         # 깊이 2단계까지
tree -d           # 디렉토리만
tree -a           # 숨김 파일 포함
tree -h           # 파일 크기 표시
tree -I 'node_modules|.git'  # 패턴 제외
tree --prune      # 빈 디렉토리 제외
tree -P '*.py'    # 특정 패턴만 표시
 
# 설치 (없는 경우)
# Debian/Ubuntu: sudo apt install tree
# Red Hat/CentOS: sudo yum install tree

파일 조작

cp - 파일/디렉토리 복사

cp source.txt dest.txt           # 파일 복사
cp source.txt /path/to/dir/      # 디렉토리로 복사
cp file1.txt file2.txt dir/      # 여러 파일을 디렉토리로 복사

주요 옵션:

옵션설명
-r, -R재귀적 복사 (디렉토리 복사 시 필수)
-p권한, 소유자, 타임스탬프 보존
-a아카이브 모드 (-dR --preserve=all). 심볼릭 링크, 권한 등 모두 보존
-i덮어쓰기 전 확인
-n기존 파일 덮어쓰지 않음
-u소스가 더 새로울 때만 복사
-v복사 과정 출력
-l복사 대신 하드 링크 생성
-s복사 대신 심볼릭 링크 생성
# 디렉토리 전체 복사 (권한 보존)
cp -rp /source/dir /dest/dir
 
# 백업 용도 - 모든 속성 보존
cp -a /home/user /backup/user_backup
 
# 진행 상황 확인 (큰 파일)
cp -v large_file.iso /mnt/usb/

mv - 파일/디렉토리 이동 및 이름 변경

mv old_name.txt new_name.txt     # 이름 변경
mv file.txt /path/to/dir/       # 파일 이동
mv dir1/ dir2/                   # 디렉토리 이동/이름 변경
mv -i file.txt /dest/           # 덮어쓰기 전 확인
mv -n file.txt /dest/           # 기존 파일 덮어쓰지 않음
mv -v file.txt /dest/           # 이동 과정 출력
 
# 동일 파일 시스템 내 mv는 inode를 유지 (매우 빠름, 실제 데이터 복사 X)
# 다른 파일 시스템 간 mv는 내부적으로 cp + rm 수행

rm - 파일/디렉토리 삭제

rm file.txt                      # 파일 삭제
rm -i file.txt                   # 확인 후 삭제
rm -f file.txt                   # 강제 삭제 (확인 없이, 에러 무시)
rm -r directory/                 # 디렉토리 재귀 삭제
rm -rf directory/                # 디렉토리 강제 재귀 삭제
 
# 주의: rm은 휴지통 없이 즉시 삭제 (정확히는 링크 해제)
# 위험한 명령 방지
rm -rf /                         # 최신 시스템에서는 --no-preserve-root 없이 거부
rm -rf /*                        # 이것은 보호되지 않으므로 극도로 주의!
 
# 안전한 사용 습관
rm -ri directory/                # -i로 각 파일마다 확인
alias rm='rm -i'                 # 별칭 설정 (선택적)

mkdir - 디렉토리 생성

mkdir dirname                    # 디렉토리 생성
mkdir -p path/to/nested/dir      # 중간 디렉토리 포함 생성 (없으면 생성)
mkdir -m 755 dirname             # 권한 지정하여 생성
mkdir dir1 dir2 dir3             # 여러 디렉토리 동시 생성
 
# 날짜별 디렉토리 생성
mkdir -p logs/$(date +%Y/%m/%d)

rmdir - 빈 디렉토리 삭제

rmdir emptydir                   # 빈 디렉토리만 삭제 (비어있지 않으면 에러)
rmdir -p path/to/nested/dir      # 중간 디렉토리도 비어 있으면 함께 삭제

touch - 파일 생성/타임스탬프 변경

touch newfile.txt                # 파일 없으면 빈 파일 생성, 있으면 타임스탬프 갱신
touch -a file.txt                # 접근 시간(atime)만 변경
touch -m file.txt                # 수정 시간(mtime)만 변경
touch -t 202401151030.00 file.txt  # 특정 시간으로 설정 (YYYYMMDDhhmm.ss)
touch -d "2024-01-15 10:30" file.txt  # 문자열로 시간 지정
touch -r ref_file.txt target.txt # ref_file의 타임스탬프를 target에 복사

검색

find - 파일 시스템에서 파일 검색

강력하고 유연한 파일 검색 도구. 실제 파일 시스템을 순회하므로 항상 최신 결과를 반환한다.

기본 문법: find [경로] [조건] [동작]

이름 기반 검색

find /home -name "*.txt"             # 이름 패턴으로 검색
find /home -iname "*.TXT"            # 대소문자 무시
find / -name "passwd"                # 정확한 이름으로 검색
find . -name "*.log" -not -name "error*"  # NOT 조건

타입 기반 검색

find . -type f                       # 일반 파일만
find . -type d                       # 디렉토리만
find . -type l                       # 심볼릭 링크만
find . -type f -name "*.py"          # 조합: .py 파일만
 
# 타입 코드:
# f: 일반 파일  d: 디렉토리  l: 심볼릭 링크
# c: 문자 장치  b: 블록 장치  p: 파이프(FIFO)  s: 소켓

크기 기반 검색

find . -size +100M                   # 100MB 초과
find . -size -1k                     # 1KB 미만
find . -size 0                       # 빈 파일 (0바이트)
find . -empty                        # 빈 파일 및 빈 디렉토리
 
# 크기 단위: c(바이트), k(KB), M(MB), G(GB)
# +: 초과, -: 미만, 접두사 없음: 정확히

시간 기반 검색

find . -mtime -7                     # 최근 7일 이내 수정된 파일
find . -mtime +30                    # 30일 이상 전에 수정된 파일
find . -atime -1                     # 최근 1일 이내 접근된 파일
find . -ctime -3                     # 최근 3일 이내 변경된 파일 (메타데이터 포함)
find . -newer reference_file         # reference_file보다 새로운 파일
find . -mmin -60                     # 최근 60분 이내 수정된 파일
 
# mtime: 수정 시간, atime: 접근 시간, ctime: 변경 시간(inode 변경 포함)
# 단위가 -time은 일(day), -min은 분(minute)

권한 기반 검색

find . -perm 644                     # 정확히 644 권한
find . -perm -644                    # 644 권한을 모두 포함 (AND)
find . -perm /644                    # 644 권한 중 하나라도 포함 (OR)
find . -perm -u+x                    # 소유자 실행 권한이 있는 파일
find / -perm -4000                   # SUID 설정된 파일
find / -perm -2000                   # SGID 설정된 파일

소유자/그룹 기반 검색

find / -user root                    # root 소유 파일
find / -group admin                  # admin 그룹 파일
find / -nouser                       # 소유자가 없는 파일 (삭제된 사용자)
find / -nogroup                      # 그룹이 없는 파일

-exec - 검색 결과에 명령 실행

# 각 파일에 대해 명령 실행 ({}: 찾은 파일명, \;: 명령 종료)
find . -name "*.tmp" -exec rm {} \;
 
# 확인 후 실행 (-ok)
find . -name "*.tmp" -ok rm {} \;
 
# 여러 파일을 한 번에 전달 (+: xargs와 유사, 더 효율적)
find . -name "*.txt" -exec grep "keyword" {} +
 
# 찾은 파일 권한 변경
find . -type f -exec chmod 644 {} +
find . -type d -exec chmod 755 {} +
 
# 찾은 파일 복사
find . -name "*.conf" -exec cp {} /backup/ \;

논리 연산자와 조합

# AND (기본값, -a)
find . -name "*.py" -size +1M
 
# OR (-o)
find . -name "*.jpg" -o -name "*.png"
 
# NOT (-not 또는 !)
find . -not -name "*.log"
find . ! -name "*.log"
 
# 괄호로 우선순위 지정 (이스케이프 필요)
find . \( -name "*.jpg" -o -name "*.png" \) -size +1M
 
# 깊이 제한
find . -maxdepth 2 -name "*.py"     # 최대 2단계까지
find . -mindepth 1 -maxdepth 1      # 현재 디렉토리만 (ls와 유사)

실전 활용 예시

# 30일 이상 된 로그 파일 삭제
find /var/log -name "*.log" -mtime +30 -delete
 
# 빈 디렉토리 정리
find /path -type d -empty -delete
 
# 특정 크기 범위의 파일 검색
find / -type f -size +100M -size -1G -exec ls -lh {} +
 
# 최근 1시간 이내 수정된 설정 파일
find /etc -name "*.conf" -mmin -60
 
# SUID 파일 보안 감사
find / -type f -perm -4000 -ls 2>/dev/null

locate - 데이터베이스 기반 빠른 검색

사전에 구축된 데이터베이스(mlocate.db)를 검색하므로 find보다 훨씬 빠르지만, 실시간이 아니다.

locate filename                      # 파일명 포함 경로 검색
locate -i filename                   # 대소문자 무시
locate -c filename                   # 매칭 개수만 출력
locate -r '\.py$'                    # 정규표현식
 
# 데이터베이스 갱신 (보통 cron으로 자동 실행)
sudo updatedb

which, whereis - 실행 파일 위치 검색

which python3                        # PATH에서 실행 파일 위치
which -a python3                     # 모든 매칭 경로
 
whereis python3                      # 바이너리, 소스, man 페이지 위치
# python3: /usr/bin/python3 /usr/lib/python3 /usr/share/man/man1/python3.1.gz
 
type python3                         # Bash 내장 - 별칭/함수/내장명령 등도 확인

링크

하드 링크

ln original.txt link.txt             # 하드 링크 생성
ls -li original.txt link.txt         # 동일한 inode 확인
 
# 하드 링크 특징:
# - 같은 파일 시스템 내에서만 가능
# - 디렉토리에 대해 불가 (일반적으로)
# - 원본 삭제해도 데이터 유지
# - 별도 inode를 사용하지 않음

심볼릭 링크

ln -s /path/to/original symlink      # 심볼릭 링크 생성
ln -s /path/to/dir dir_link          # 디렉토리 심볼릭 링크
ln -sf /new/target symlink           # 기존 링크 강제 덮어쓰기
 
readlink symlink                     # 링크 대상 확인
readlink -f symlink                  # 최종 실제 경로 (체인 해석)
 
# 깨진 심볼릭 링크 찾기
find . -xtype l
 
# 심볼릭 링크 특징:
# - 파일 시스템 간에도 가능
# - 디렉토리에 대해 가능
# - 원본 삭제 시 깨진 링크(dangling link) 됨
# - 별도 inode 사용, 크기 = 경로 문자열 길이

사용 사례:

# 버전별 라이브러리 관리
/usr/lib/libfoo.so -> libfoo.so.2
/usr/lib/libfoo.so.2 -> libfoo.so.2.1.3
 
# 설정 파일 공유 (dotfiles 관리)
ln -s ~/dotfiles/.bashrc ~/.bashrc
 
# 현재 실행 버전 관리
ln -s /opt/app-v2.1 /opt/app-current

압축/아카이브

tar - 아카이브 (묶기/풀기)

tar는 여러 파일을 하나로 묶는 아카이브 도구. 자체적으로 압축은 아니지만 압축 프로그램과 결합하여 사용한다.

핵심 옵션 구조: tar [동작][압축][옵션] 아카이브파일 대상

동작설명
ccreate - 아카이브 생성
xextract - 아카이브 풀기
tlist - 아카이브 내용 목록
압축설명확장자
zgzip.tar.gz / .tgz
jbzip2.tar.bz2
Jxz.tar.xz
(없음)압축 없음.tar
기타 옵션설명
v상세 출력 (verbose)
f아카이브 파일 지정 (항상 마지막 옵션으로)
C대상 디렉토리 지정 (풀 위치)
--exclude특정 패턴 제외
-p권한 보존
# === 아카이브 생성 ===
# 단순 아카이브 (압축 없음)
tar cvf archive.tar file1 file2 dir/
 
# gzip 압축 아카이브
tar czvf archive.tar.gz dir/
 
# bzip2 압축 아카이브 (더 높은 압축률, 더 느림)
tar cjvf archive.tar.bz2 dir/
 
# xz 압축 아카이브 (최고 압축률, 가장 느림)
tar cJvf archive.tar.xz dir/
 
# 특정 파일/디렉토리 제외
tar czvf backup.tar.gz --exclude='*.log' --exclude='.git' project/
 
# === 아카이브 풀기 ===
tar xvf archive.tar                  # tar 풀기
tar xzvf archive.tar.gz              # gzip 풀기
tar xjvf archive.tar.bz2             # bzip2 풀기
tar xJvf archive.tar.xz              # xz 풀기
tar xzvf archive.tar.gz -C /dest/    # 특정 디렉토리에 풀기
 
# === 아카이브 내용 확인 ===
tar tvf archive.tar.gz               # 내용 목록 보기 (풀지 않고)
 
# === 실전 예시 ===
# 백업 (날짜 포함)
tar czvf backup-$(date +%Y%m%d).tar.gz /home/user/
 
# 특정 파일만 추출
tar xzvf archive.tar.gz path/to/specific/file

gzip / gunzip - gzip 압축

gzip file.txt                # file.txt -> file.txt.gz (원본 삭제)
gzip -k file.txt             # 원본 유지 (-k: keep)
gzip -d file.txt.gz          # 압축 해제 (= gunzip)
gunzip file.txt.gz           # 압축 해제
gzip -9 file.txt             # 최고 압축률 (1~9, 기본 6)
gzip -l file.txt.gz          # 압축 정보 (원본 크기, 압축률)
 
# 단일 파일만 압축 가능 - 여러 파일은 tar와 조합

bzip2 - bzip2 압축

gzip보다 높은 압축률, 느린 속도.

bzip2 file.txt               # file.txt -> file.txt.bz2
bzip2 -k file.txt            # 원본 유지
bzip2 -d file.txt.bz2        # 압축 해제 (= bunzip2)
bunzip2 file.txt.bz2         # 압축 해제

zip / unzip - ZIP 형식

Windows 호환이 필요할 때 주로 사용.

zip archive.zip file1 file2            # 파일 압축
zip -r archive.zip directory/          # 디렉토리 재귀 압축
zip -e archive.zip file.txt            # 암호화 ZIP
zip -9 archive.zip file.txt            # 최고 압축률
 
unzip archive.zip                      # 현재 디렉토리에 풀기
unzip archive.zip -d /dest/            # 특정 디렉토리에 풀기
unzip -l archive.zip                   # 내용 목록 보기 (풀지 않고)
unzip -o archive.zip                   # 덮어쓰기 확인 없이

xz - xz 압축

가장 높은 압축률. 속도는 가장 느림.

xz file.txt                  # file.txt -> file.txt.xz
xz -k file.txt               # 원본 유지
xz -d file.txt.xz            # 압축 해제 (= unxz)
unxz file.txt.xz             # 압축 해제
xz -9 file.txt               # 최고 압축률

압축 방식 비교

방식확장자압축률속도비고
gzip.gz보통빠름가장 널리 사용
bzip2.bz2좋음보통gzip보다 느리지만 압축률 높음
xz.xz최고느림배포판 패키지에 많이 사용
zip.zip보통빠름크로스 플랫폼 호환성

파일 정보

file - 파일 타입 판별

확장자가 아닌 파일 내용(매직 바이트)으로 타입을 판별한다.

file document.pdf
# document.pdf: PDF document, version 1.4
 
file script.sh
# script.sh: Bourne-Again shell script, ASCII text executable
 
file /bin/ls
# /bin/ls: ELF 64-bit LSB pie executable, x86-64 ...
 
file image.jpg
# image.jpg: JPEG image data, JFIF standard 1.01
 
file mystery_file              # 확장자 없는 파일도 판별 가능

stat - 파일 상세 정보

stat file.txt
# File: file.txt
# Size: 1234        Blocks: 8       IO Block: 4096   regular file
# Device: 801h/2049d   Inode: 5678901   Links: 1
# Access: (0644/-rw-r--r--)  Uid: (1000/user)  Gid: (1000/user)
# Access: 2024-01-15 10:30:00.123456789 +0900   (atime)
# Modify: 2024-01-15 10:25:00.987654321 +0900   (mtime)
# Change: 2024-01-15 10:25:00.987654321 +0900   (ctime)
#  Birth: 2024-01-10 09:00:00.000000000 +0900   (생성 시간, 지원 시)
 
# 타임스탬프 설명:
# atime (Access time) : 마지막 읽기 시간
# mtime (Modify time) : 마지막 내용 수정 시간
# ctime (Change time) : 마지막 메타데이터 변경 시간 (권한, 소유자 등)
 
# 커스텀 포맷 출력
stat -c '%n: size=%s, inode=%i, links=%h' file.txt
# file.txt: size=1234, inode=5678901, links=1

du - 디스크 사용량 확인

du -sh directory/              # 디렉토리 전체 크기 (요약)
du -sh *                       # 현재 디렉토리 항목별 크기
du -sh /var/log/*              # /var/log 하위 항목별 크기
du -h --max-depth=1            # 1단계 하위까지 크기
du -ah directory/              # 모든 파일 포함 크기
 
# 가장 큰 디렉토리/파일 찾기
du -sh /home/* | sort -rh | head -10
 
# 옵션:
# -s : 요약 (summarize)
# -h : 사람이 읽기 좋은 크기 (human-readable)
# -a : 파일도 포함 (all)
# -c : 총합 표시
# --max-depth=N : 깊이 제한

wc - 줄/단어/문자 수 카운트

wc file.txt
#  100  450 3200 file.txt
#  줄   단어 바이트
 
wc -l file.txt                 # 줄 수만
wc -w file.txt                 # 단어 수만
wc -c file.txt                 # 바이트 수만
wc -m file.txt                 # 문자 수 (멀티바이트 지원)
wc -l *.py                     # 여러 파일 + 합계
 
# 파이프와 함께
cat file.txt | wc -l           # 파이프로 줄 수 세기
find . -name "*.py" | wc -l    # .py 파일 개수

와일드카드 / 글로빙 (Globbing)

셸이 파일명 패턴을 확장하는 기능. 명령어가 아니라 셸의 기능이다.

기본 와일드카드

패턴설명예시
*0개 이상의 모든 문자*.txt - 모든 .txt 파일
?정확히 1개의 문자file?.txt - file1.txt, fileA.txt
[...]괄호 안 문자 중 하나file[123].txt - file1.txt, file2.txt, file3.txt
[^...] / [!...]괄호 안 문자 제외file[^0-9].txt - 숫자가 아닌 것
[a-z]범위 지정file[a-z].txt - filea.txt ~ filez.txt

Brace Expansion (중괄호 확장)

글로빙이 아닌 셸 확장. 파일 존재 여부와 무관하게 문자열을 생성한다.

echo {a,b,c}                   # a b c
echo file{1,2,3}.txt           # file1.txt file2.txt file3.txt
echo {1..10}                   # 1 2 3 4 5 6 7 8 9 10
echo {a..z}                    # a b c ... z
echo {01..10}                  # 01 02 03 ... 10 (zero-padding)
 
# 실전 활용
mkdir -p project/{src,test,docs,config}
cp file.txt{,.bak}             # file.txt를 file.txt.bak으로 복사
mv file.{txt,md}               # file.txt를 file.md로 이름 변경

Extended Globbing (**)

Bash에서는 globstar 옵션을 활성화해야 한다.

# globstar 활성화 (Bash 4+)
shopt -s globstar
 
# 재귀적으로 모든 .py 파일 매칭
ls **/*.py
 
# zsh에서는 기본 지원

글로빙 vs 정규표현식

특성글로빙정규표현식
사용 위치셸 명령줄grep, sed, awk 등
*0개 이상 모든 문자앞 문자 0회 이상 반복
?정확히 1개 문자앞 문자 0 또는 1회
.리터럴 점아무 문자 1개

중요: 글로빙에서 *는 “모든 문자열”을 의미하지만, 정규표현식에서 *는 “앞 문자 반복”을 의미한다. 혼동 주의.

xargs 활용

표준 입력에서 받은 데이터를 명령어의 인자로 변환하여 실행한다. find-exec와 유사하지만 더 유연하다.

# 기본 사용
echo "file1 file2 file3" | xargs rm
 
# find와 조합 - 가장 흔한 패턴
find . -name "*.tmp" | xargs rm
find . -name "*.py" | xargs grep "import os"
 
# 공백/특수문자가 포함된 파일명 처리 (-0: NULL 구분자)
find . -name "*.txt" -print0 | xargs -0 rm
 
# 한 번에 처리할 인자 수 제한
echo {1..100} | xargs -n 10 echo    # 10개씩 처리
 
# 각 인자를 특정 위치에 배치 (-I)
find . -name "*.bak" | xargs -I {} mv {} /backup/
cat urls.txt | xargs -I {} curl -O {}
 
# 병렬 실행 (-P: 프로세스 수)
find . -name "*.png" | xargs -P 4 -I {} convert {} -resize 50% resized/{}
 
# xargs vs find -exec:
# xargs는 한 번에 여러 인자를 전달하여 프로세스 생성 오버헤드를 줄인다
# find -exec {} + 도 동일한 최적화를 제공한다
# 파일명에 특수문자가 있다면 반드시 -print0 | xargs -0 사용

실전 활용 예시

# 여러 파일에서 특정 문자열 치환
find . -name "*.py" -print0 | xargs -0 sed -i 's/old_func/new_func/g'
 
# git에서 추적하지 않는 파일 삭제
git ls-files --others --exclude-standard | xargs rm
 
# 프로세스 일괄 종료
pgrep -f "pattern" | xargs kill
 
# 파일 목록을 tar로 압축
find . -name "*.log" -mtime +7 | xargs tar czvf old_logs.tar.gz
 
# 결과 개수 확인
find . -name "*.py" | xargs wc -l | tail -1   # 전체 줄 수 합계