2026.08.19 | 전공자·정보처리기사 수준 | 인프라 직무 대비 | 총 60문항 · ★★★ 최빈출 / ★★ 자주 출제 / ★ 기본
이 파일 하나로 모든 단원이 포함되어 있어 어디로 옮겨도 동작합니다.
| 단원 | |
|---|---|
| 리눅스 기초와 파일 시스템 | 10문항 |
| 사용자 권한과 프로세스 관리 | 10문항 |
| 쉘 스크립트 기본 문법 | 10문항 |
| 쉘 스크립트로 자동화하기 | 10문항 |
| 파이썬 기초 문법 | 10문항 |
| 인프라 자동화를 위한 파이썬 | 10문항 |
대상: 전공자 · 정보처리기사 취득자 | 목적: 인프라 직무(네트워크·클라우드·시스템·보안) 기술 면접 대비 중요도: ★★★ 최빈출 · ★★ 자주 출제 · ★ 기본 개념
답안
리눅스는 FHS(Filesystem Hierarchy Standard)라는 표준에 따라 디렉토리 구조가 정해져 있으며, 최상위는 루트(/) 디렉토리입니다. /bin, /sbin에는 시스템 부팅과 운영에 필요한 필수 실행 파일이, /etc에는 시스템 설정 파일이 위치합니다. /home은 사용자 계정별 홈 디렉토리, /var는 로그·캐시처럼 실행 중 변화하는 가변 데이터, /tmp는 임시 파일을 저장합니다. /proc, /sys는 실제 디스크 파일이 아니라 커널이 실시간으로 제공하는 프로세스·시스템 정보를 담은 가상 파일 시스템이라는 점이 자주 출제됩니다. /usr에는 사용자용 응용 프로그램과 라이브러리가, /lib에는 공유 라이브러리가 위치합니다.
관련 개념 FHS, 가상 파일 시스템, /proc, /etc, 루트 파일 시스템
답안 ext4는 리눅스의 오랜 표준 파일 시스템으로, 저널링을 지원해 비정상 종료 시에도 데이터 무결성을 유지하고 안정성이 검증되어 있습니다. XFS는 대용량 파일과 고성능 I/O에 강점이 있어 서버 및 스토리지 환경에서 많이 사용되며, 온라인 상태에서 파일 시스템 크기를 늘릴 수 있습니다. Btrfs는 스냅샷, 체크섬, 통합 볼륨 관리(RAID 유사 기능) 등 고급 기능을 제공하는 차세대 파일 시스템입니다. 이 외에 네트워크를 통해 파일을 공유하는 NFS, 윈도우와 호환되는 FAT32/NTFS도 자주 언급됩니다. 면접에서는 "왜 저널링 파일 시스템이 필요한가"로 이어지는 경우가 많으므로 저널링의 목적(비정상 종료 시 복구 시간 단축)을 함께 알아두는 것이 좋습니다.
관련 개념 저널링, ext4, XFS, Btrfs, 파일 시스템 포맷
답안
inode는 리눅스 파일 시스템에서 파일 하나하나에 대한 메타데이터를 저장하는 자료구조로, 파일의 실제 데이터가 아니라 파일에 대한 "속성 정보"를 담습니다. 여기에는 파일 크기, 소유자(UID/GID), 권한, 생성·수정·접근 시간, 데이터 블록의 위치를 가리키는 포인터 등이 포함되지만, 파일명은 inode에 저장되지 않고 디렉토리 엔트리(파일명-inode 번호 매핑)에 별도로 저장됩니다. 이 때문에 같은 inode를 여러 파일명이 가리킬 수 있는데 이것이 하드링크의 원리입니다. inode 개수는 파일 시스템 생성 시 고정되므로, 디스크 용량이 남아 있어도 inode가 모두 소진되면 더 이상 파일을 생성할 수 없는 상황이 발생할 수 있습니다(df -i로 확인). 이 개념은 하드링크/심볼릭링크, df -i를 통한 장애 진단 질문으로 자연스럽게 이어집니다.
관련 개념 디렉토리 엔트리, df -i, 하드링크, 메타데이터, 데이터 블록
답안
하드링크는 동일한 inode를 가리키는 또 하나의 디렉토리 엔트리로, 원본 파일과 완전히 동등하며 원본을 삭제해도 링크 카운트가 0이 되기 전까지 데이터는 유지됩니다. 반면 심볼릭링크(소프트링크)는 원본 파일의 경로 문자열을 담고 있는 별도의 파일(별도 inode)로, 원본이 삭제되면 "깨진 링크(dangling link)"가 됩니다. 하드링크는 같은 파일 시스템(파티션) 내에서만 생성 가능하고 디렉토리에는 만들 수 없지만, 심볼릭링크는 파일 시스템 경계를 넘어 생성할 수 있고 디렉토리도 링크할 수 있습니다. 명령어로는 ln이 하드링크, ln -s가 심볼릭링크를 생성합니다. 실무에서는 설정 파일 버전 전환이나 배포 디렉토리 스위칭에 심볼릭링크가 자주 사용됩니다.
관련 개념 inode, ln -s, 링크 카운트, dangling link, 파일 시스템 경계
답안
마운트는 물리적인 디스크 파티션이나 외부 저장장치, 네트워크 파일 시스템을 리눅스의 특정 디렉토리(마운트 포인트)에 연결해 하나의 디렉토리 트리 안에서 접근할 수 있도록 하는 과정입니다. mount 명령으로 수동 마운트할 수 있지만, 시스템 부팅 시 자동으로 마운트되도록 하려면 /etc/fstab 파일에 장치, 마운트 포인트, 파일 시스템 종류, 옵션, 덤프/검사 순서를 기록해 둡니다. 마운트 해제는 umount로 하며, 파일이 사용 중이면 "device is busy" 오류가 발생할 수 있어 lsof나 fuser로 사용 중인 프로세스를 확인하는 경우가 많습니다. 클라우드 환경에서는 EBS/블록 스토리지를 인스턴스에 연결한 뒤 파티셔닝, 포맷, 마운트, fstab 등록까지의 흐름이 실무 질문으로 자주 나옵니다.
관련 개념 /etc/fstab, umount, 마운트 포인트, lsof, 블록 디바이스
답안
절대경로는 루트(/)부터 시작해 대상 파일까지의 전체 경로를 명시하는 방식으로 현재 작업 디렉토리와 무관하게 항상 동일한 위치를 가리킵니다. 상대경로는 현재 작업 디렉토리를 기준으로 한 경로이며 .(현재 디렉토리), ..(상위 디렉토리)를 활용합니다. 스크립트를 어디서 실행하든 안정적으로 동작하게 하려면 절대경로 사용이 권장됩니다. 파일 디스크립터(FD)는 프로세스가 열어 놓은 파일이나 소켓 등을 가리키는 정수 형태의 식별자로, 기본적으로 0번은 표준입력(stdin), 1번은 표준출력(stdout), 2번은 표준에러(stderr)로 예약되어 있습니다. 리다이렉션이나 파이프는 결국 이 파일 디스크립터를 재연결하는 동작입니다.
관련 개념 stdin/stdout/stderr, 현재 작업 디렉토리, 심볼릭 경로, FD 번호
답안
df(disk free)는 파일 시스템 단위로 마운트된 디스크 전체의 사용량과 여유 공간을 보여주는 명령으로, "이 파티션에 얼마나 남았는가"를 확인할 때 사용합니다. du(disk usage)는 특정 디렉토리나 파일이 실제로 차지하는 용량을 계산하는 명령으로, "어떤 디렉토리가 용량을 많이 차지하는가"를 파악할 때 사용합니다. 두 값이 다르게 보이는 대표적인 상황은 삭제된 파일을 어떤 프로세스가 여전히 열고 있는 경우로, 이때 df상의 사용량은 줄지 않지만 du로는 해당 파일이 보이지 않는 불일치가 발생할 수 있습니다. 실무에서는 du -sh */ | sort -rh처럼 조합해 용량을 많이 차지하는 디렉토리를 빠르게 찾는 방식이 자주 쓰입니다. 이 차이는 디스크 풀(disk full) 장애 트러블슈팅에서 핵심 질문으로 자주 등장합니다.
관련 개념 디스크 풀 트러블슈팅, lsof를 통한 삭제된 열린 파일 확인, 파일 시스템 단위 vs 디렉토리 단위, sort -rh
답안 저널링(journaling)은 파일 시스템에 실제 변경을 적용하기 전에 그 변경 내용을 별도의 로그(저널) 영역에 먼저 기록해 두는 기법입니다. 정전이나 시스템 크래시처럼 갑작스러운 종료가 발생해도, 재부팅 시 전체 디스크를 처음부터 검사(fsck)할 필요 없이 저널에 기록된 내용만 확인해 미완료된 트랜잭션을 롤백하거나 재적용함으로써 빠르게 일관된 상태로 복구할 수 있습니다. 저널링이 없던 초창기 파일 시스템(ext2 등)은 비정상 종료 시 전체 디스크 검사에 매우 오랜 시간이 걸렸다는 점과 대비해서 설명하면 좋습니다. 다만 모든 쓰기 작업을 저널에도 기록하므로 약간의 성능 오버헤드가 발생할 수 있어, 메타데이터만 저널링할지 데이터까지 저널링할지 선택 가능한 모드가 존재합니다. ext4, XFS 등 현대 리눅스 파일 시스템 대부분이 저널링을 기본으로 채택하고 있습니다.
관련 개념 fsck, 크래시 복구, 트랜잭션 로그, ext2 대비, 메타데이터 저널링
답안
전원이 켜지면 먼저 하드웨어를 초기화하는 BIOS/UEFI가 실행되어 자체 진단(POST)을 수행한 뒤 부팅 장치를 찾습니다. 이후 부트로더(GRUB 등)가 로드되어 사용자가 선택한 커널 이미지와 초기 램디스크(initramfs)를 메모리에 적재합니다. 커널이 실행되면 하드웨어를 인식하고 초기 프로세스인 init(현대 배포판에서는 systemd)를 최초 프로세스(PID 1)로 실행합니다. systemd는 설정된 타겟(target, 과거 runlevel에 대응)에 따라 필요한 서비스와 데몬들을 순차적/병렬적으로 기동하며, 이 과정이 끝나면 로그인 화면이나 셸 프롬프트가 제공되어 사용자가 로그인할 수 있는 상태가 됩니다. 이 흐름은 "커널 패닉은 어느 단계에서 발생하는가", "PID 1이 왜 특별한가" 같은 꼬리질문으로 이어지기 쉽습니다.
관련 개념 GRUB, initramfs, PID 1, systemd target, 커널 패닉
답안
find는 디렉토리 트리를 순회하며 이름, 크기, 수정 시간, 권한 등 다양한 조건으로 파일을 검색할 수 있는 명령으로, -exec 옵션을 통해 검색된 파일에 바로 다른 명령을 적용할 수 있습니다. grep은 파일 내용 중 특정 패턴(문자열/정규식)이 포함된 줄을 검색하는 명령이며, -r로 재귀 검색, -i로 대소문자 무시, -n으로 줄 번호 출력이 가능합니다. locate는 사전에 구축된 파일 인덱스 데이터베이스를 검색하므로 find보다 훨씬 빠르지만 실시간 반영이 되지 않는 단점이 있습니다. 이 외에 which/whereis로 실행 파일 위치를 확인하는 것도 자주 쓰입니다. 이 명령어들은 파이프(|)와 결합해 로그 분석이나 자동화 스크립트에서 핵심적으로 활용됩니다.
관련 개념 find -exec, grep -r/-i/-n, locate와 updatedb, which/whereis, 파이프 활용
대상: 전공자 · 정보처리기사 취득자 | 목적: 인프라 직무(네트워크·클라우드·시스템·보안) 기술 면접 대비 중요도: ★★★ 최빈출 · ★★ 자주 출제 · ★ 기본 개념
답안
리눅스는 다중 사용자 운영체제로, 모든 파일과 프로세스는 특정 사용자(UID)와 그룹(GID)에 소속됩니다. /etc/passwd에는 사용자 계정명, UID, GID, 홈 디렉토리, 기본 셸 등 계정 정보가 저장되며 시스템의 모든 사용자가 읽을 수 있습니다. /etc/shadow에는 실제 암호화된 비밀번호와 비밀번호 만료 정책이 저장되며 root만 읽을 수 있도록 권한이 제한되어 있는데, 이는 과거 /etc/passwd에 평문에 가까운 해시가 그대로 노출되어 있던 보안 문제를 해결하기 위해 분리된 것입니다. 그룹 정보는 /etc/group에 저장되며, 한 사용자는 하나의 기본(primary) 그룹과 여러 개의 보조(secondary) 그룹에 속할 수 있습니다. 이 구조는 파일 권한 체계(소유자/그룹/기타) 및 sudo 권한 부여 방식과 직접 연결됩니다.
관련 개념 UID/GID, /etc/shadow 권한, primary/secondary 그룹, /etc/group, 쉐도우 패스워드 분리
답안
리눅스 파일 권한은 소유자(owner), 그룹(group), 기타(other) 세 주체에 대해 각각 읽기(r=4), 쓰기(w=2), 실행(x=1) 권한을 부여하는 구조입니다. 예를 들어 chmod 754 file은 소유자에게 rwx(7), 그룹에게 r-x(5), 기타에게 r--(4) 권한을 부여합니다. 기호 표기법은 chmod u+x,g-w,o=r file처럼 u(user)/g(group)/o(other)/a(all)와 +/-/=를 조합해 특정 권한만 변경할 수 있습니다. 디렉토리에서 실행(x) 권한은 파일 목록이 아니라 해당 디렉토리 내부로 진입(cd)하거나 파일에 접근할 수 있는 권한을 의미한다는 점이 자주 헷갈리는 포인트로 출제됩니다. 소유자와 그룹 변경은 chown, chgrp으로 수행합니다.
관련 개념 chown/chgrp, SUID/SGID/Sticky bit, 디렉토리 실행권한의 의미, 8진수 권한 표기
답안
umask는 새로 생성되는 파일과 디렉토리의 기본 권한에서 "빼줄" 권한을 지정하는 마스크 값입니다. 리눅스에서 파일의 기본 최대 권한은 666(rw-rw-rw-), 디렉토리는 777(rwxrwxrwx)이며, 여기에 umask 값을 비트 단위로 빼서 실제 생성 권한이 결정됩니다. 예를 들어 umask가 022이면 파일은 666-022=644(rw-r--r--), 디렉토리는 777-022=755(rwxr-xr-x)로 생성됩니다. 파일에는 기본적으로 실행 권한이 부여되지 않기 때문에 umask 계산 시 실행 비트가 이미 0인 자리는 그대로 유지된다는 점에 유의해야 합니다. umask는 ~/.bashrc나 /etc/profile에 설정해 사용자별/시스템 전역 기본 권한 정책을 관리하는 데 사용됩니다.
관련 개념 기본 권한 666/777, umask 022, .bashrc 설정, 보안 정책 기본값
답안
R(Running/Runnable)은 실제로 CPU를 사용 중이거나 실행 대기열에 있는 상태이고, S(Sleeping, interruptible)는 특정 이벤트(입력, 타이머 등)를 기다리며 대기 중이지만 시그널에 의해 깨어날 수 있는 상태입니다. D(Uninterruptible Sleep)는 주로 디스크 I/O 완료를 기다리는 상태로, 시그널로도 깨울 수 없어 이 상태가 오래 지속되면 하드웨어나 I/O 병목 문제를 의심해야 합니다. Z(Zombie)는 프로세스가 종료되었지만 부모 프로세스가 wait()로 종료 상태를 회수하지 않아 프로세스 테이블에 정보만 남아 있는 상태이고, T(Stopped)는 SIGSTOP 등으로 일시 정지된 상태입니다. ps aux나 top의 STAT 컬럼에서 이 상태들을 확인할 수 있으며, 특히 D 상태와 Z 상태는 장애 진단에서 자주 다뤄집니다.
관련 개념 ps aux STAT, D 상태와 I/O 병목, 좀비 프로세스, top, SIGSTOP/SIGCONT
답안
시그널은 프로세스에게 특정 이벤트가 발생했음을 비동기적으로 알리는 소프트웨어 인터럽트입니다. SIGTERM(15)은 프로세스에게 "정상적으로 종료해 달라"고 요청하는 신호로, 프로세스가 이를 받아 자원 정리 후 스스로 종료할 기회를 가지며 프로세스가 직접 핸들러를 등록해 가로챌 수 있습니다. SIGKILL(9)은 커널이 프로세스를 즉시 강제 종료시키는 신호로, 프로세스가 이를 가로채거나 무시할 수 없어 자원 정리 없이 바로 종료되므로 최후의 수단으로만 사용해야 합니다. SIGHUP(1)은 원래 터미널 연결이 끊겼음을 알리는 신호였으나 현재는 많은 데몬에서 "설정 파일을 재로드하라"는 용도로도 관행적으로 사용됩니다. SIGINT(2)는 사용자가 Ctrl+C를 눌렀을 때 발생하는 신호로 SIGTERM과 마찬가지로 가로채거나 무시할 수 있습니다. kill -9를 남용하면 데이터 정합성 문제가 생길 수 있다는 점이 실무 면접에서 자주 강조됩니다.
관련 개념 kill -9 vs kill -15, 시그널 핸들러, nohup, trap, graceful shutdown
답안
데몬은 사용자와의 직접적인 상호작용(터미널 입출력) 없이 백그라운드에서 지속적으로 실행되며 특정 서비스를 제공하는 프로세스로, 이름 끝에 흔히 d가 붙습니다(예: sshd, httpd, crond). 데몬은 일반적으로 부모 프로세스와의 연결을 끊고(제어 터미널 분리) 독립적인 세션을 생성하는 더블 포크(double fork) 방식으로 생성되어 부모 프로세스가 종료되어도 영향을 받지 않습니다. 표준입출력을 /dev/null이나 로그 파일로 재지정해 터미널 종료와 무관하게 계속 실행되도록 하는 것이 일반적입니다. 현대 리눅스에서는 systemd가 데몬의 생성, 모니터링, 재시작을 관리하는 표준적인 방식으로 자리 잡았습니다.
관련 개념 더블 포크, 제어 터미널 분리, systemd unit, nohup/setsid
답안
전통적인 SysVinit은 /etc/rc.d의 런레벨(runlevel) 스크립트를 순차적으로 실행하는 방식으로, 서비스 간 의존 관계 처리가 단순하고 병렬 처리가 어려워 부팅 속도가 느린 편이었습니다. systemd는 PID 1로 동작하며 서비스 간 의존성을 명시적으로 선언하고 병렬로 기동할 수 있어 부팅 속도를 크게 개선했고, 유닛(unit) 파일 단위로 서비스, 소켓, 타이머, 마운트 등을 통합 관리합니다. systemctl start/stop/restart/status로 서비스를 제어하고, systemctl enable로 부팅 시 자동 시작 여부를 설정하며, journalctl로 로그를 통합 조회할 수 있는 점이 실무에서 자주 활용됩니다. 런레벨 개념은 systemd의 target(예: multi-user.target, graphical.target)으로 대체되었습니다.
관련 개념 유닛 파일, systemctl enable/status, journalctl, target vs runlevel
답안
cron은 지정된 시각이나 주기에 맞춰 명령어나 스크립트를 자동으로 실행해 주는 데몬(crond)이며, 사용자는 crontab -e로 자신의 스케줄을 등록합니다. crontab 표기법은 분 시 일 월 요일 명령어 순서의 5개 필드로 구성되며, *는 모든 값, */5는 5단위 간격, 1-5는 범위, 1,3,5는 특정 값 나열을 의미합니다. 예를 들어 0 2 * * * /home/user/backup.sh는 매일 새벽 2시에 백업 스크립트를 실행하라는 의미입니다. 시스템 전체 작업은 /etc/crontab이나 /etc/cron.d/에 사용자명을 포함해 등록하며, cron 환경에서는 사용자의 로그인 셸 환경변수(PATH 등)가 로드되지 않는 경우가 많아 스크립트 내에서 절대경로를 사용하거나 환경변수를 명시적으로 설정해야 하는 점이 실무에서 자주 지적되는 함정입니다.
관련 개념 crontab -e, */5 * * * *, /etc/cron.d, PATH 환경변수 문제, anacron
답안
좀비 프로세스는 자식 프로세스가 실행을 마치고 종료(exit)했지만, 부모 프로세스가 wait() 시스템 콜을 호출해 종료 상태 코드를 회수하지 않아 프로세스 테이블에 최소한의 정보만 남아 있는 상태입니다. 좀비 프로세스는 실제 자원을 거의 사용하지 않지만 프로세스 테이블 슬롯을 차지하므로, 대량으로 쌓이면 새로운 프로세스를 생성할 수 없는 문제가 발생할 수 있습니다. 고아 프로세스는 반대로 부모 프로세스가 자식보다 먼저 종료된 경우로, 이때 커널은 해당 자식 프로세스를 init(또는 systemd, PID 1)의 자식으로 재입양시켜 정상적으로 회수(reap)되도록 처리합니다. 즉 좀비는 부모가 살아있는데 회수를 안 하는 문제, 고아는 부모가 먼저 죽는 상황이라는 차이가 핵심입니다. 좀비 프로세스를 없애려면 부모 프로세스를 종료시키거나(재입양되어 init이 회수) 부모 코드에서 wait()를 호출하도록 수정해야 합니다.
관련 개념 wait()/waitpid(), PID 1 재입양, 프로세스 테이블, fork-exec 모델
답안
su는 다른 사용자(기본값은 root)로 완전히 전환하는 명령으로, 대상 계정의 비밀번호를 알아야 하며 전환 이후에는 해당 사용자 권한으로 셸이 계속 유지됩니다. sudo는 자신의 계정 비밀번호로 인증한 뒤 /etc/sudoers에 정의된 정책에 따라 특정 명령어만 관리자 권한으로 일시적으로 실행하는 방식으로, 실행되는 모든 명령이 로그에 기록되어 감사(audit) 추적이 가능하다는 보안상의 장점이 있습니다. sudo는 사용자별로 실행 가능한 명령어를 세밀하게 제한할 수 있어 root 비밀번호를 여러 사람과 공유할 필요가 없다는 점에서 다중 관리자 환경에 더 적합합니다. visudo 명령으로 /etc/sudoers를 안전하게 편집하는 것이 권장됩니다.
관련 개념 /etc/sudoers, visudo, 감사 로그, 최소 권한 원칙
대상: 전공자 · 정보처리기사 취득자 | 목적: 인프라 직무(네트워크·클라우드·시스템·보안) 기술 면접 대비 중요도: ★★★ 최빈출 · ★★ 자주 출제 · ★ 기본 개념
답안
쉬뱅은 스크립트 파일 첫 줄에 #!/bin/bash처럼 작성해 이 스크립트를 어떤 인터프리터로 실행할지 커널에게 알려주는 지시자입니다. 쉬뱅이 없으면 현재 사용 중인 셸이 스크립트를 해석하려 시도하므로 이식성 문제가 생길 수 있어, #!/usr/bin/env bash처럼 환경에 따라 인터프리터 경로를 유연하게 찾는 방식도 널리 쓰입니다. 변수는 NAME=value 형태로 선언하며 등호 앞뒤에 공백이 있으면 안 되고, 값을 참조할 때는 $NAME 또는 ${NAME}을 사용합니다. 셸 변수는 기본적으로 문자열로 취급되며, 다른 프로세스에도 값을 물려주려면 export로 환경변수로 승격시켜야 합니다. readonly로 상수를 선언하거나 unset으로 변수를 제거하는 것도 기본 문법에 포함됩니다.
관련 개념 #!/usr/bin/env, export, readonly, 환경변수 vs 셸 변수
답안
if 문은 if [ 조건 ]; then ... elif [ 조건 ]; then ... else ... fi 구조로 작성하며, 대괄호 [ ]는 사실 test 명령어의 다른 표현이므로 대괄호 안팎에 공백을 반드시 넣어야 합니다. 문자열 비교는 =/!=, 숫자 비교는 -eq/-ne/-gt/-lt 등을 사용하며, 파일 존재 여부는 -f(일반 파일), -d(디렉토리), -e(존재) 등으로 확인합니다. 최신 bash에서는 이중 대괄호 [[ ]]를 사용하면 패턴 매칭이나 논리 연산자(&&, ||)를 더 안전하게 쓸 수 있습니다. case 문은 하나의 변수 값을 여러 패턴과 비교해 분기할 때 if-elif보다 가독성이 좋으며, case $var in pattern1) ... ;; pattern2) ... ;; *) ... ;; esac 형태로 작성하고 각 분기는 ;;로 종료합니다.
관련 개념 [ ] vs [[ ]], test 명령어, 파일 테스트 연산자(-f/-d/-e), case의 ;; 종료
답안
for 문은 리스트나 범위를 순회할 때 사용하며 for i in 1 2 3; do ... done처럼 값 목록을 직접 순회하거나, for file in *.log; do ... done처럼 파일 글롭 패턴을, 또는 for ((i=0; i<10; i++))처럼 C 스타일 산술 반복도 지원합니다. while 문은 조건이 참인 동안 반복하는 구조로 while [ 조건 ]; do ... done 형태이며, 파일을 한 줄씩 읽어 처리할 때 while read -r line; do ... done < file.txt와 같은 패턴이 로그 처리 자동화에서 매우 자주 사용됩니다. 무한 루프는 while true; do ... done으로 만들고 break로 탈출, continue로 다음 반복으로 건너뛸 수 있습니다. read -r에서 -r 옵션은 백슬래시를 이스케이프 문자로 해석하지 않도록 막아주므로 파일을 읽을 때는 관례적으로 항상 붙이는 것이 좋습니다.
관련 개념 while read -r, 파일 글롭, break/continue, C 스타일 for, IFS
답안
셸 함수는 function_name() { 명령어들 } 형태로 정의하며, function 키워드는 bash에서는 선택 사항입니다. 함수 내부에서 전달받은 인자는 $1, $2처럼 위치 매개변수로 접근하고, 전체 인자 개수는 $#, 모든 인자는 $@나 $*로 참조합니다. 다른 프로그래밍 언어와 달리 셸 함수는 값을 return으로 반환할 때 정수(0~255) 형태의 종료 상태 코드만 반환할 수 있으므로, 문자열 결과값이 필요하면 echo로 출력한 뒤 호출부에서 $(function_name)처럼 커맨드 치환으로 받아야 합니다. 함수 내에서 선언한 변수를 함수 지역 변수로 한정하려면 local 키워드를 사용해야 하며, 이를 생략하면 기본적으로 전역 변수가 되어 스크립트 다른 부분과 충돌할 수 있습니다.
관련 개념 local 변수, $1/$#/$@, 커맨드 치환 $(), return 코드 제한
답안
리다이렉션은 프로세스의 표준입출력을 파일이나 다른 대상으로 연결을 바꾸는 기능입니다. >는 표준출력을 파일에 덮어쓰기로 저장하고, >>는 기존 내용 끝에 이어 붙입니다(append). <는 파일 내용을 표준입력으로 넘겨주며, 2>는 표준에러(FD 2)만 파일로 리다이렉션합니다. 표준출력과 표준에러를 모두 하나의 파일로 합치려면 command > file.log 2>&1처럼 순서에 유의해서 작성해야 하며(먼저 stdout을 파일로 보낸 뒤 stderr를 stdout이 가리키는 곳으로 복사), 최신 bash에서는 &>로 한 번에 처리할 수도 있습니다. 에러 메시지를 무시하고 싶을 때는 2>/dev/null로 버리는 패턴이 로그 자동화 스크립트에서 매우 자주 사용됩니다.
관련 개념 2>&1의 순서, /dev/null, append vs overwrite, FD 재지정
답안
파이프(|)는 한 명령어의 표준출력을 다른 명령어의 표준입력으로 바로 연결해 주는 IPC 메커니즘으로, 커널이 두 프로세스 사이에 커널 버퍼(파이프 버퍼)를 만들어 중간에 임시 파일을 거치지 않고 데이터를 흘려보냅니다. 이를 이용해 여러 명령어를 조합해 복잡한 텍스트 처리 파이프라인을 구성할 수 있는데, 예를 들어 ps aux | grep nginx | awk '{print $2}'는 nginx 관련 프로세스만 걸러내 PID만 추출합니다. 파이프로 연결된 각 명령어는 병렬적으로(스트리밍 방식으로) 실행되며, 앞 명령의 출력이 생성되는 대로 뒤 명령이 소비할 수 있어 대용량 로그도 메모리 효율적으로 처리할 수 있습니다. 파이프라인 전체의 종료 코드는 기본적으로 마지막 명령의 종료 코드를 따르며, 중간 명령의 실패까지 확인하려면 PIPESTATUS 배열이나 set -o pipefail을 사용해야 합니다.
관련 개념 프로세스 간 통신(IPC), PIPESTATUS, pipefail, 스트리밍 처리
답안
리눅스의 모든 명령어와 스크립트는 종료될 때 0~255 사이의 정수 종료 코드(exit status)를 반환하며, 관례상 0은 성공, 0이 아닌 값은 실패나 특정 오류 상황을 의미합니다. 방금 실행한 명령의 종료 코드는 특수 변수 $?로 즉시 확인할 수 있으며, 다음 명령을 실행하면 값이 갱신되므로 필요한 시점에 바로 확인해야 합니다. 스크립트 안에서 exit N을 호출하면 그 시점에서 스크립트 실행을 즉시 종료하고 N을 자신의 종료 코드로 반환하며, exit을 생략하면 스크립트의 마지막 명령의 종료 코드가 그대로 사용됩니다. 이 값은 command1 && command2(성공 시에만 다음 실행), command1 || command2(실패 시에만 다음 실행) 같은 논리 연산자와 결합해 자동화 스크립트의 흐름 제어에 핵심적으로 활용됩니다.
관련 개념 $?, exit N, && / ||, 관례적 종료 코드 의미
답안
$0은 실행 중인 스크립트 자신의 이름(경로)을 가리키고, $1, $2...는 스크립트에 전달된 위치 인자를 의미합니다. $#은 전달된 인자의 총 개수, $@는 모든 인자를 개별 항목으로, $*는 모든 인자를 하나의 문자열로 결합해 나타냅니다("$@"처럼 큰따옴표로 감쌌을 때 이 둘의 동작 차이가 뚜렷해집니다). $$는 현재 실행 중인 스크립트(셸)의 PID이고, $!는 가장 최근에 백그라운드로 실행한 프로세스의 PID를 담고 있어 백그라운드 작업을 나중에 wait $!로 기다리거나 종료시킬 때 활용됩니다. 이 변수들은 로그 파일명에 PID를 붙이거나, 인자 개수를 검증해 사용법 오류를 처리하는 스크립트에서 자주 사용됩니다.
관련 개념 "$@" vs "$*", 위치 매개변수, wait $!, PID 기반 로그 파일명
답안
bash에서 배열은 arr=(a b c)처럼 괄호로 값을 나열해 선언하며, 개별 요소는 ${arr[0]}처럼 인덱스로 접근합니다(인덱스는 0부터 시작). 배열 전체 요소는 ${arr[@]}로, 요소 개수는 ${#arr[@]}로 확인할 수 있으며, for item in "${arr[@]}"; do ... done처럼 순회할 때는 요소에 공백이 포함될 수 있으므로 반드시 큰따옴표로 감싸는 것이 안전합니다. 배열에 요소를 추가할 때는 arr+=("new")를 사용하고, 연관 배열(키-값 쌍)을 쓰려면 declare -A로 선언해야 합니다. 배열은 여러 서버 목록을 순회하며 동일 작업을 반복하는 자동화 스크립트에서 자주 활용됩니다.
관련 개념 ${arr[@]}, declare -A, "${arr[@]}"의 안전한 인용, 연관 배열
답안
작은따옴표('...')로 감싼 문자열은 내부의 모든 문자를 있는 그대로 취급해 변수 치환($)이나 커맨드 치환이 전혀 일어나지 않습니다. 큰따옴표("...")로 감싼 문자열은 변수 치환($VAR)과 커맨드 치환($(...))은 그대로 수행하지만, 파일명 글롭 확장이나 단어 분리(word splitting)는 막아줍니다. 예를 들어 공백이 포함된 파일 경로를 다룰 때 $FILE처럼 인용 없이 쓰면 단어 분리로 인해 여러 인자로 쪼개져 스크립트 오류의 흔한 원인이 되므로, 변수를 참조할 때는 습관적으로 "$FILE"처럼 큰따옴표로 감싸는 것이 안전한 스크립팅의 기본 원칙입니다. 반대로 정규식이나 리터럴 문자열을 그대로 전달해야 할 때는 작은따옴표가 더 적합합니다.
관련 개념 단어 분리(word splitting), 글롭 확장 방지, 커맨드 치환, 변수 인용 습관
대상: 전공자 · 정보처리기사 취득자 | 목적: 인프라 직무(네트워크·클라우드·시스템·보안) 기술 면접 대비 중요도: ★★★ 최빈출 · ★★ 자주 출제 · ★ 기본 개념
답안
서버가 계속 운영되면 애플리케이션과 시스템 로그가 무한정 쌓여 디스크 공간을 고갈시키고, 파일 하나가 지나치게 커지면 grep이나 열람 도구로 조회하는 속도도 느려집니다. 로그 로테이션은 일정 크기나 주기가 되면 현재 로그 파일을 백업용 이름으로 옮기고(예: access.log를 access.log.1로) 새 빈 파일을 생성해 애플리케이션이 계속 로그를 쓸 수 있게 하는 기법입니다. 리눅스에서는 logrotate 데몬/도구가 /etc/logrotate.conf와 /etc/logrotate.d/ 아래의 설정에 따라 이 작업을 자동으로 수행하며, 압축(compress), 보관 개수(rotate N), 로테이션 주기(daily/weekly), 로테이션 후 프로세스에 신호를 보내 로그 파일 핸들을 다시 열게 하는 postrotate 스크립트 등을 설정할 수 있습니다. 애플리케이션이 로그 파일을 이미 열어 놓은 상태에서 파일명만 바뀌면 계속 옛 inode에 쓰게 되므로, postrotate에서 SIGHUP 등을 보내 파일을 다시 열도록 하는 처리가 중요합니다.
관련 개념 logrotate.d, postrotate, SIGHUP 재오픈, compress/rotate 옵션, 디스크 풀 방지
답안
배치 작업은 사람의 개입 없이 정해진 시각이나 조건에 자동으로 실행되므로, 먼저 멱등성(idempotency)을 고려해 같은 작업이 중복 실행되어도 결과가 왜곡되지 않도록 설계해야 합니다. 실행 중 다른 인스턴스가 겹쳐 실행되는 것을 막기 위해 락 파일(lock file)이나 flock 명령을 사용해 동시 실행을 방지하는 것이 일반적입니다. 실패했을 때를 대비해 로그를 남기고 알림(메일, 슬랙 등)을 보내는 처리, 그리고 재시도 로직을 넣어 일시적 오류에 강건하게 만드는 것이 중요합니다. 또한 작업 실행 시간이 다음 실행 주기를 넘기지 않도록 타임아웃을 설정하고, 처리 대상 데이터가 예상과 다를 경우(빈 파일, 형식 오류 등) 안전하게 중단할 수 있는 검증 로직도 함께 설계해야 합니다.
관련 개념 flock 락 파일, 멱등성, 타임아웃, 실패 알림, 재시도 로직
답안
grep은 파일이나 표준입력에서 지정한 패턴과 일치하는 줄을 찾아 출력하는 텍스트 검색 도구입니다. -i는 대소문자를 구분하지 않고, -v는 패턴과 일치하지 않는 줄만 역으로 출력하며, -r(또는 -R)은 디렉토리를 재귀적으로 탐색합니다. -n은 일치한 줄의 번호를 함께 출력하고, -c는 일치한 줄의 개수만 세며, -l은 패턴이 포함된 파일명만 나열합니다. -E(또는 egrep)를 사용하면 확장 정규표현식을 사용할 수 있어 +, ?, | 같은 메타문자를 이스케이프 없이 바로 쓸 수 있고, -A/-B/-C 옵션으로 일치한 줄의 앞뒤 컨텍스트 줄까지 함께 출력할 수 있어 로그 분석 시 매우 유용합니다.
관련 개념 -i/-v/-r/-n, 확장 정규표현식(-E), -A/-B/-C 컨텍스트, egrep
답안
sed(Stream EDitor)는 입력을 한 줄씩 읽어 패턴 공간(pattern space)에 담아 지정된 편집 명령을 적용한 뒤 결과를 출력하는 스트림 편집 도구입니다. 가장 많이 쓰이는 치환 명령은 sed 's/패턴/대체문자열/g' 형태로, s는 substitute(치환)를 의미하고 끝의 g(global) 플래그는 한 줄 안의 모든 일치 항목을 치환하며 생략하면 각 줄의 첫 번째 일치 항목만 치환합니다. 원본 파일을 직접 수정하려면 -i 옵션(sed -i 's/foo/bar/g' file.txt)을 사용하며, macOS의 BSD sed는 -i ''처럼 백업 확장자를 명시해야 하는 등 GNU sed와 옵션 차이가 있어 이식성에 유의해야 합니다. 특정 줄 범위만 처리하려면 sed -n '5,10p' file처럼 주소(라인 번호나 정규식)를 지정할 수 있고, 여러 설정 파일의 특정 값을 일괄 치환하는 자동화 스크립트에서 자주 사용됩니다.
관련 개념 sed -i, s/pattern/repl/g, GNU vs BSD sed 차이, 라인 주소 지정
답안
awk는 입력을 줄 단위로 읽고 각 줄을 공백(기본 구분자, -F로 변경 가능) 기준으로 필드(field)로 나눈 뒤, 패턴에 매칭되는 줄에 대해 지정된 액션을 실행하는 텍스트 처리 언어입니다. 필드는 $1, $2처럼 순서대로 접근하고, $0은 현재 줄 전체를 의미하며, NR은 현재까지 읽은 줄 번호, NF는 현재 줄의 필드 개수를 담고 있습니다. 예를 들어 awk -F: '{print $1, $3}' /etc/passwd는 콜론(:)을 구분자로 사용자명(1번 필드)과 UID(3번 필드)를 출력합니다. awk는 BEGIN{}과 END{} 블록을 지원해 처리 전/후에 초기화나 합계 출력 같은 작업을 할 수 있고, 변수 저장과 조건문·반복문까지 지원하는 하나의 미니 프로그래밍 언어이기 때문에 grep이나 sed보다 복잡한 로그 집계(예: 특정 필드 합산, 카운트)에 훨씬 강력합니다.
관련 개념 -F 구분자, NR/NF, BEGIN/END 블록, $0/$1 필드 참조, 로그 집계
답안
정규표현식에서 .은 임의의 문자 하나를, *는 바로 앞 문자가 0회 이상 반복됨을, +(확장 정규식)는 1회 이상 반복을, ?는 0회 또는 1회를 의미합니다. ^는 줄의 시작, $는 줄의 끝을 나타내는 앵커(anchor)이며, []는 문자 집합(예: [0-9]는 숫자 하나)을, [^...]는 부정 집합을 의미합니다. {n,m}은 반복 횟수 범위를 지정하고, |(확장 정규식)는 OR 조건을 나타내 여러 패턴 중 하나라도 일치하면 매칭됩니다. grep, sed, awk 모두 정규표현식을 사용하지만 기본 정규식(BRE)과 확장 정규식(ERE)에서 +, ?, |, {} 등을 이스케이프해야 하는지가 도구별로 다르므로, grep -E처럼 확장 모드 옵션 유무를 확인하는 것이 중요합니다.
관련 개념 BRE vs ERE, 앵커(^/$), 문자 집합 [], 반복 {n,m}, grep -E
답안
기본적으로 bash 스크립트는 어떤 명령이 실패(0이 아닌 종료 코드)해도 다음 줄을 계속 실행하는데, set -e를 스크립트 상단에 선언하면 명령이 실패하는 즉시 스크립트 실행을 중단시켜 오류를 조기에 감지할 수 있습니다. set -u는 선언되지 않은 변수를 참조할 때 오류로 처리해 오타로 인한 빈 변수 사용을 방지하고, 이 둘과 앞서 다룬 set -o pipefail을 함께 사용하는 set -euo pipefail은 자동화 스크립트에서 사실상 표준적인 안전장치로 권장됩니다. trap은 스크립트가 특정 시그널을 받거나 종료(EXIT)될 때 실행할 명령을 등록하는 기능으로, 예를 들어 trap 'rm -f "$TMPFILE"' EXIT를 걸어두면 스크립트가 정상 종료되든 중간에 실패하든 항상 임시 파일을 정리하도록 보장할 수 있습니다. 이런 기법들은 배치 작업이 어중간한 상태로 실패해 데이터 정합성을 해치는 상황을 방지하는 데 핵심적입니다.
관련 개념 set -euo pipefail, trap EXIT, 임시 파일 정리, 선언되지 않은 변수 오류
답안
cron으로 실행되는 스크립트는 사용자가 로그인해서 얻는 셸 환경과 달리 매우 최소한의 환경변수(PATH 등)만 가진 채로 실행되므로, 스크립트 안에서 사용하는 명령어나 파일 경로는 반드시 절대경로로 작성하거나 스크립트 초반에 PATH를 명시적으로 설정해야 합니다. cron은 기본적으로 표준출력/에러를 등록된 관리자 메일로 보내려 시도하는데, 메일 시스템이 구성되어 있지 않으면 출력이 유실될 수 있으므로 >> /var/log/myjob.log 2>&1처럼 로그 파일로 명시적으로 리다이렉션하는 것이 안전합니다. 또한 스크립트 자체에서 앞서 다룬 종료 코드와 로깅을 남겨야 실패를 사후에 파악할 수 있고, 실행 시간이 예상보다 길어져 다음 스케줄과 겹치지 않도록 flock으로 중복 실행을 방지하는 것이 좋습니다. 시간대(timezone) 설정이 서버와 다르면 의도치 않은 시각에 실행될 수 있다는 점도 확인이 필요합니다.
관련 개념 PATH 명시, 리다이렉션으로 로그 남기기, flock 중복 방지, 타임존 확인
답안
find로 조건에 맞는 파일 목록을 찾은 뒤, xargs를 이용해 그 목록을 다른 명령의 인자로 넘겨 일괄 처리하는 패턴은 대량 파일 작업 자동화에서 매우 흔합니다. 예를 들어 find /var/log -name "*.log" -mtime +30 -print0 | xargs -0 rm -f는 30일 이상 지난 로그 파일을 찾아 한꺼번에 삭제합니다. 여기서 -print0와 xargs -0을 함께 쓰는 이유는 파일명에 공백이나 개행이 포함되어 있어도 널(null) 문자를 구분자로 사용해 안전하게 분리하기 위함입니다. find의 -exec 옵션으로도 동일한 작업을 할 수 있지만(find ... -exec rm -f {} \;), 대상 파일이 매우 많을 경우 xargs가 여러 파일을 묶어 명령을 적은 횟수로 실행하기 때문에 성능상 더 유리한 경우가 많습니다.
관련 개념 -print0 / xargs -0, find -exec 비교, -mtime 조건, 성능(호출 횟수)
답안
set -x를 스크립트에 추가하면 실행되는 각 명령어와 확장된 변수 값을 실행 전에 그대로 화면에 출력해 주어, 스크립트가 실제로 어떤 명령으로 치환되어 실행되는지 한 줄씩 추적할 수 있습니다. 특정 구간만 디버깅하고 싶다면 그 구간 앞뒤에 set -x와 set +x(디버그 종료)를 배치하면 됩니다. 실행 전에 잠재적 버그를 잡고 싶다면 정적 분석 도구인 shellcheck를 사용하는 것이 좋은데, 이는 인용 부호 누락, 잘못된 비교 연산자 사용, 사용하지 않는 변수 등 흔한 셸 스크립팅 실수를 규칙 기반으로 지적해 줍니다. 이 외에도 bash -n script.sh로 실제 실행 없이 문법 오류만 검사(syntax check)할 수 있어, CI 파이프라인에 셸 스크립트 검증 단계로 넣기에 적합합니다.
관련 개념 set -x/+x, shellcheck 정적 분석, bash -n 문법 검사, CI 통합
대상: 전공자 · 정보처리기사 취득자 | 목적: 인프라 직무(네트워크·클라우드·시스템·보안) 기술 면접 대비 중요도: ★★★ 최빈출 · ★★ 자주 출제 · ★ 기본 개념
답안
리스트(list)는 순서가 있고 중복을 허용하며 변경 가능(mutable)한 자료형으로 대괄호 []로 표현하고, 원소 추가·삭제·변경이 자유로워 가장 범용적으로 사용됩니다. 튜플(tuple)은 리스트와 비슷하게 순서가 있지만 한 번 생성되면 변경 불가능(immutable)하다는 점이 핵심 차이이며, 이 덕분에 딕셔너리의 키로 사용할 수 있고 함수에서 여러 값을 안전하게 묶어 반환할 때 자주 쓰입니다. 딕셔너리(dict)는 키-값 쌍으로 데이터를 저장하는 해시 기반 자료구조로 키를 통해 O(1)에 가까운 평균 시간복잡도로 값에 접근할 수 있으며, 파이썬 3.7 이상에서는 삽입 순서를 유지합니다. 집합(set)은 중복을 허용하지 않고 순서가 없는 자료형으로 합집합·교집합·차집합 같은 집합 연산과 중복 제거에 유용합니다. 변경 가능 여부(mutable/immutable)가 어떤 자료형을 딕셔너리 키나 집합 원소로 쓸 수 있는지를 결정한다는 점이 자주 출제됩니다.
관련 개념 mutable/immutable, 해시 가능(hashable), 딕셔너리 키 제약, 집합 연산
답안
파이썬은 중괄호 대신 들여쓰기(indentation)로 코드 블록을 구분하는 것이 문법적 특징이며, if/elif/else로 조건 분기를 작성합니다. for 문은 for item in iterable: 형태로 반복 가능한(iterable) 객체를 순회하며, C 언어처럼 인덱스 기반 카운터를 직접 다루기보다 range()나 enumerate()를 함께 활용하는 방식이 파이썬다운(Pythonic) 스타일로 권장됩니다. while 문은 조건이 참인 동안 반복하며 break/continue로 흐름을 제어합니다. 리스트 컴프리헨션은 [표현식 for 항목 in 반복가능객체 if 조건] 형태로 반복문과 조건문을 한 줄로 압축해 새로운 리스트를 생성하는 문법으로, 가독성과 실행 속도 모두에서 일반 for 루프보다 유리한 경우가 많습니다.
관련 개념 들여쓰기 기반 블록, enumerate/range, 리스트 컴프리헨션, Pythonic 스타일
답안
파이썬 함수는 고정된 개수의 매개변수 외에 *args를 사용해 임의 개수의 위치 인자를 튜플 형태로 받을 수 있고, kwargs를 사용해 임의 개수의 키워드 인자를 딕셔너리 형태로 받을 수 있습니다. 예를 들어 def func(a, b, *args, kwargs):로 정의하면 a, b는 필수 인자로, 그 이후에 넘어오는 위치 인자들은 args 튜플에, key=value 형태로 넘어오는 인자들은 kwargs 딕셔너리에 모입니다. 이 문법은 인자 개수가 가변적인 유틸리티 함수를 만들거나, 다른 함수에 인자를 그대로 전달(위임)하는 래퍼(wrapper) 함수를 작성할 때 유용합니다. 함수 정의 시 매개변수 순서는 일반 위치 인자, *args, 기본값이 있는 키워드 전용 인자, **kwargs 순서를 지켜야 문법 오류가 나지 않습니다.
관련 개념 위치 인자 vs 키워드 인자, 인자 언패킹(*, **), 래퍼 함수, 기본값 매개변수
답안
파이썬은 오류 발생 가능성이 있는 코드를 try 블록에 작성하고, 특정 예외가 발생했을 때 처리할 로직을 except 블록에 작성하는 방식으로 예외를 처리합니다. except는 except ValueError:처럼 특정 예외 타입을 지정해 세분화된 처리를 할 수 있고, 여러 개의 except 블록을 순서대로 배치해 서로 다른 예외를 각각 다르게 처리할 수 있으며, 가능한 한 except:처럼 모든 예외를 무차별적으로 잡는 방식은 원인 파악을 어렵게 하므로 지양하는 것이 좋습니다. else 블록은 try 블록에서 예외가 발생하지 않았을 때만 실행되고, finally 블록은 예외 발생 여부와 관계없이 항상 실행되므로 파일 닫기, 네트워크 연결 해제 같은 자원 정리 코드를 넣기에 적합합니다. 예외를 발생시키려면 raise를 사용하며, 자신만의 예외 클래스를 만들려면 Exception을 상속받아 정의할 수 있습니다.
관련 개념 raise, 사용자 정의 예외, else 블록, finally를 통한 자원 정리, with문(context manager)
답안
파이썬 프로젝트마다 필요한 패키지와 그 버전이 다를 수 있는데, 시스템에 전역으로 패키지를 설치하면 프로젝트 간에 의존성 버전 충돌이 발생하거나 한 프로젝트의 패키지 업그레이드가 다른 프로젝트를 망가뜨릴 수 있습니다. 가상환경(virtual environment)은 프로젝트별로 독립된 파이썬 인터프리터와 패키지 설치 공간을 만들어 이런 충돌을 방지하는 기법으로, 표준 라이브러리인 venv 모듈을 이용해 python -m venv myenv 명령으로 생성하고 source myenv/bin/activate로 활성화해 사용합니다. 활성화된 가상환경 안에서 pip install로 패키지를 설치하면 시스템 전역이 아니라 해당 가상환경 디렉토리 안에만 설치되어 격리성이 보장됩니다. 이 외에도 virtualenv, conda, pipenv, poetry 등 유사한 목적의 도구들이 있으며, 인프라 자동화 스크립트를 배포할 때도 실행 환경을 재현 가능하게 만들기 위해 가상환경 사용이 권장됩니다.
관련 개념 python -m venv, activate/deactivate, 의존성 충돌, conda/poetry
답안
pip은 파이썬의 표준 패키지 관리 도구로, PyPI(Python Package Index)에 등록된 패키지를 pip install 패키지명으로 설치하거나 pip uninstall로 제거할 수 있습니다. 프로젝트가 의존하는 패키지 목록과 버전을 requirements.txt 파일에 패키지명==버전 형태로 명시해 두면, 다른 개발자나 서버에서 pip install -r requirements.txt 한 줄로 동일한 의존성 환경을 재현할 수 있어 "내 컴퓨터에서는 되는데" 문제를 줄이는 데 도움이 됩니다. 현재 설치된 패키지 목록을 파일로 저장하려면 pip freeze > requirements.txt를 사용합니다. 버전을 정확히 고정(==)하면 재현성은 높아지지만 보안 패치를 놓칠 수 있고, 범위 지정(>=)은 유연하지만 예상치 못한 호환성 문제가 생길 수 있어 운영 환경에서는 보통 고정 버전을 사용하는 경우가 많습니다.
관련 개념 pip freeze, PyPI, 버전 고정 vs 범위 지정, 의존성 재현성
답안
얕은 복사는 객체의 최상위 컨테이너만 새로 만들고, 그 안에 담긴 내부 객체(중첩된 리스트, 딕셔너리 등)는 원본과 동일한 참조를 그대로 공유하는 방식으로, list.copy(), list(원본), 슬라이싱(원본[:]), copy.copy() 등으로 수행할 수 있습니다. 이 때문에 중첩된 리스트를 얕은 복사한 뒤 내부 리스트의 원소를 변경하면 원본도 함께 바뀌는 예상치 못한 부작용(side effect)이 발생할 수 있습니다. 깊은 복사는 copy.deepcopy()를 사용해 최상위 객체뿐 아니라 내부의 모든 중첩 객체까지 재귀적으로 완전히 새로 복제하므로 원본과 복사본이 완전히 독립적으로 동작합니다. 단순한 1차원 리스트나 불변(immutable) 원소만 담긴 자료구조라면 얕은 복사로도 충분하지만, 리스트 안에 리스트가 있는 것처럼 중첩 구조를 다룰 때는 의도에 맞게 깊은 복사를 선택해야 버그를 예방할 수 있습니다.
관련 개념 copy.deepcopy, 참조 공유 부작용, 중첩 자료구조, 슬라이싱 복사
답안
파이썬에서 모듈(module)은 함수, 클래스, 변수 등을 담고 있는 하나의 .py 파일을 의미하며, import 모듈명으로 다른 파일에서 불러와 재사용할 수 있습니다. 패키지(package)는 여러 모듈을 디렉토리 단위로 묶은 것으로, 해당 디렉토리에 __init__.py 파일이 있으면(파이썬 3.3 이후로는 없어도 네임스페이스 패키지로 인식되지만 명시적으로 두는 것이 일반적) 패키지로 인식되어 from 패키지명 import 모듈명처럼 계층적으로 임포트할 수 있습니다. __init__.py는 패키지가 임포트될 때 실행되는 초기화 코드를 담을 수 있고, 패키지의 공개 API를 정의하는 용도로도 활용됩니다. 이런 구조 덕분에 대규모 프로젝트를 기능 단위로 나누어 체계적으로 관리하고, 다른 프로젝트에서도 재사용 가능한 라이브러리 형태로 배포할 수 있습니다.
관련 개념 __init__.py, import/from import, 네임스페이스 패키지, 상대 임포트
답안
GIL은 CPython 인터프리터에서 한 순간에 오직 하나의 스레드만 파이썬 바이트코드를 실행할 수 있도록 강제하는 전역 락으로, 파이썬 객체의 메모리 관리(참조 카운팅)를 여러 스레드가 동시에 건드려 발생할 수 있는 경합 상태를 막기 위해 도입되었습니다. 이 때문에 멀티스레딩을 사용해도 CPU 연산이 많은(CPU-bound) 작업은 여러 코어를 동시에 활용하지 못해 성능 향상이 제한적이며, 오히려 스레드 간 락 전환 오버헤드로 단일 스레드보다 느려지는 경우도 있습니다. 반대로 파일 입출력이나 네트워크 대기처럼 I/O 바운드 작업은 대기 시간 동안 GIL이 해제되므로 멀티스레딩이 여전히 효과적입니다. CPU 바운드 작업에서 진짜 병렬성이 필요하다면 GIL의 영향을 받지 않는 별도 프로세스를 사용하는 multiprocessing 모듈을 사용하는 것이 일반적인 해결책입니다.
관련 개념 CPU-bound vs I/O-bound, multiprocessing, 참조 카운팅, CPython 한정 특성
답안
==는 두 객체의 값(내용)이 같은지를 비교하는 연산자로, 리스트나 문자열처럼 서로 다른 객체라도 담고 있는 내용이 동일하면 True를 반환합니다. is는 두 변수가 동일한 객체(메모리 상 동일한 identity)를 참조하고 있는지를 비교하는 연산자로, 내용이 같아도 서로 다른 객체라면 False를 반환합니다. 예를 들어 a = [1,2,3]; b = [1,2,3]일 때 a == b는 True이지만 a is b는 서로 다른 리스트 객체이므로 False입니다. 다만 작은 정수나 문자열 리터럴처럼 파이썬이 내부적으로 캐싱하거나 인터닝(interning)하는 값들은 is 비교에서도 True가 나올 수 있어 혼동을 주기 쉬운데, 이런 최적화에 의존하지 말고 값 비교에는 ==를, None 비교에는 관례적으로 is None을 사용하는 것이 올바른 방식입니다.
관련 개념 identity vs equality, 정수/문자열 인터닝, is None 관례, id() 함수
대상: 전공자 · 정보처리기사 취득자 | 목적: 인프라 직무(네트워크·클라우드·시스템·보안) 기술 면접 대비 중요도: ★★★ 최빈출 · ★★ 자주 출제 · ★ 기본 개념
답안
subprocess 모듈은 파이썬에서 셸 명령어나 외부 프로그램을 실행하고 그 결과를 제어하기 위한 표준 방법으로, 과거에 쓰이던 os.system이나 os.popen보다 더 세밀하고 안전한 제어를 제공해 현재는 이 모듈 사용이 권장됩니다. subprocess.run()은 명령을 실행하고 완료될 때까지 기다린 뒤 종료 코드, 표준출력, 표준에러를 담은 결과 객체를 반환하는 가장 널리 쓰이는 고수준 API로, capture_output=True로 출력을 캡처하고 check=True로 지정하면 명령이 실패(0이 아닌 종료 코드)했을 때 CalledProcessError 예외를 자동으로 발생시켜 에러 처리를 강제할 수 있습니다. 명령어는 ["ls", "-l", "/tmp"]처럼 리스트 형태로 전달하는 것이 권장되는데, shell=True와 함께 문자열을 그대로 전달하면 사용자 입력이 섞였을 때 셸 인젝션(shell injection) 취약점으로 이어질 수 있기 때문입니다. 더 정교한 제어(실시간 스트리밍 출력, 파이프 연결 등)가 필요하면 저수준 API인 subprocess.Popen을 직접 사용할 수 있습니다.
관련 개념 subprocess.run vs Popen, shell=True 인젝션 위험, check=True, CalledProcessError
답안
os 모듈은 운영체제와 상호작용하는 다양한 기능을 제공하며, 파일 시스템 관점에서는 os.listdir()로 디렉토리 내 목록을 조회하고, os.mkdir()/os.makedirs()로 디렉토리를 생성(후자는 중첩 경로를 한 번에 생성 가능)하며, os.remove()/os.rmdir()로 파일과 빈 디렉토리를 삭제합니다. 경로 관련 작업은 os.path.join()으로 운영체제에 맞는 구분자를 사용해 경로를 안전하게 조합하고, os.path.exists()/os.path.isfile()/os.path.isdir()로 존재 여부와 종류를 확인하며, os.environ을 통해 환경변수를 읽거나 설정할 수 있습니다. 최신 파이썬에서는 객체지향적인 pathlib 모듈(Path 클래스)이 경로 조작을 더 직관적으로 표현할 수 있어 점차 많이 대체되고 있지만, os 모듈은 여전히 프로세스 정보(os.getpid()), 환경변수 등 폭넓은 시스템 인터페이스를 제공한다는 점에서 함께 알아두어야 합니다.
관련 개념 os.path.join, pathlib.Path, os.environ, os.walk 재귀 탐색
답안
logging 모듈은 단순 print문과 달리 로그 레벨별 필터링, 다양한 출력 대상(콘솔, 파일, 원격 서버 등), 형식(타임스탬프, 모듈명 등) 지정을 표준화된 방식으로 지원하는 파이썬 표준 로깅 프레임워크입니다. 로그 레벨은 심각도가 낮은 순서대로 DEBUG < INFO < WARNING < ERROR < CRITICAL로 구성되며, 로거의 레벨을 특정 값으로 설정하면 그보다 낮은 레벨의 로그는 출력되지 않아 개발 중에는 DEBUG로 상세히, 운영 환경에서는 INFO나 WARNING 이상만 남기는 식으로 조절할 수 있습니다. logging.getLogger(__name__)으로 모듈별 로거를 생성하고, Handler(예: FileHandler, StreamHandler)와 Formatter를 조합해 로그를 파일에 남기면서 동시에 콘솔에도 출력하는 등 유연한 구성이 가능합니다. 운영 자동화 스크립트에서는 예외 발생 시 logger.exception()을 사용하면 스택 트레이스까지 함께 기록되어 장애 원인 파악에 큰 도움이 됩니다.
관련 개념 DEBUG~CRITICAL 레벨, Handler/Formatter, logger.exception, getLogger(__name__)
답안
requests는 파이썬에서 HTTP 요청을 간결하게 다룰 수 있게 해주는 대표적인 서드파티 라이브러리로, requests.get(url, params={...}), requests.post(url, json={...})처럼 직관적인 함수로 REST API를 호출할 수 있습니다. 응답 객체의 .status_code로 HTTP 상태 코드를 확인하고, .json()으로 JSON 응답 본문을 파이썬 딕셔너리로 바로 변환할 수 있어 API 자동화에 매우 편리합니다. 실무에서 자주 놓치는 부분은 타임아웃 미설정인데, timeout 파라미터를 지정하지 않으면 상대 서버가 응답하지 않을 때 요청이 무한정 대기해 자동화 스크립트 전체가 멈출 수 있으므로 반드시 명시해야 합니다. 또한 API 인증 토큰이나 비밀번호 같은 민감 정보는 코드에 하드코딩하지 말고 환경변수나 별도 시크릿 관리 도구를 통해 주입하는 것이 보안상 바람직하며, 일시적 네트워크 오류에 대비해 재시도 로직(requests의 Session과 HTTPAdapter를 활용한 retry 전략 등)을 함께 구성하는 것이 안정적인 자동화의 핵심입니다.
관련 개념 timeout 설정, .json() 파싱, 인증 토큰 환경변수 관리, retry/backoff
답안
파일을 열 때는 open()을 직접 호출한 뒤 close()를 잊는 실수를 방지하기 위해 with open(...) as f: 구문(컨텍스트 매니저)을 사용하는 것이 표준적인 방법으로, 블록을 벗어나면 예외가 발생하더라도 파일이 자동으로 닫혀 자원 누수를 방지합니다. 텍스트 파일은 f.read(), f.readlines(), 또는 for line in f:로 한 줄씩 순회하며 읽을 수 있고, 인코딩 문제를 피하기 위해 open(path, encoding="utf-8")처럼 인코딩을 명시하는 것이 권장됩니다. 구조화된 데이터를 다룰 때는 표준 라이브러리인 csv 모듈로 csv.reader/csv.writer 또는 csv.DictReader/DictWriter를 사용해 CSV를 다루고, json 모듈로 json.load()/json.dump()를 사용해 JSON 파일을 파이썬 객체와 상호 변환할 수 있습니다. 설정 파일이나 API 응답 데이터를 자동화 스크립트에서 파싱할 때 이 두 모듈이 매우 자주 사용됩니다.
관련 개념 with문 컨텍스트 매니저, csv.DictReader, json.load/dump, 인코딩 명시
답안
인프라 자동화 스크립트는 사람이 실수로 두 번 실행하거나 재시도 로직에 의해 여러 번 실행될 가능성이 항상 있으므로, 몇 번을 실행하든 결과가 동일하게 유지되는 멱등성(idempotency)을 설계 원칙으로 삼아야 합니다. 예를 들어 "리소스를 생성하라"는 스크립트라면 실행 전에 이미 존재하는지 확인한 뒤 없을 때만 생성하도록 작성하는 식입니다. 실제 변경을 가하기 전에 어떤 작업이 수행될지 미리 확인할 수 있도록 --dry-run 옵션을 제공하는 것도 실무에서 매우 중요한 패턴으로, 운영 환경에 영향을 주는 스크립트일수록 dry-run 모드로 먼저 검증한 뒤 실제 실행하는 습관이 사고를 예방합니다. 이 외에도 하드코딩을 피하고 설정값을 환경변수나 설정 파일로 분리하는 것, 각 단계의 성공/실패를 명확히 로깅하는 것, 그리고 부분 실패 시 이미 적용된 변경을 되돌릴 수 있는 롤백 경로를 고려하는 것이 견고한 운영 스크립트의 핵심 요소입니다.
관련 개념 dry-run 옵션, 롤백 설계, 설정 외부화, 사전 상태 확인
답안
네트워크 호출이나 외부 API 연동처럼 일시적인 오류가 발생할 수 있는 작업에서는 실패 즉시 전체 스크립트를 중단시키기보다 일정 횟수만큼 재시도하는 것이 안정성을 높입니다. 이때 실패할 때마다 곧바로 재시도하면 상대 서버에 부담을 가중시킬 수 있으므로, 재시도 간격을 점점 늘려가는 지수 백오프(exponential backoff)(예: 1초, 2초, 4초, 8초 대기)를 적용하는 것이 일반적이며, 여러 클라이언트가 동시에 같은 타이밍에 재시도하는 것을 막기 위해 대기 시간에 무작위성을 더하는 지터(jitter)를 함께 사용하기도 합니다. 파이썬에서는 이를 직접 구현하거나 tenacity, backoff 같은 서드파티 라이브러리, 또는 requests의 HTTPAdapter에 Retry 객체를 연결해 자동화할 수 있습니다. 다만 모든 실패를 무한정 재시도하면 근본 원인을 놓칠 수 있으므로, 최대 재시도 횟수를 제한하고 최종 실패 시에는 명확한 에러 로그와 알림을 남기는 것이 중요합니다.
관련 개념 exponential backoff, jitter, tenacity/backoff 라이브러리, 최대 재시도 횟수 제한
답안
파이썬 스크립트를 정기적으로 실행하는 가장 간단한 방법은 3단원/4단원에서 다룬 cron의 crontab 항목에 python3 /절대경로/script.py처럼 인터프리터 경로와 스크립트 경로를 모두 절대경로로 등록하는 것으로, cron 환경에서는 로그인 셸의 PATH나 가상환경이 활성화되어 있지 않으므로 가상환경을 사용하는 경우 /venv/bin/python3처럼 가상환경 내 인터프리터를 직접 지정해야 합니다. 좀 더 현대적인 방식으로는 systemd timer를 사용할 수 있는데, .service 유닛에 실행할 파이썬 스크립트를, .timer 유닛에 실행 주기를 정의하면 journalctl을 통한 통합 로그 조회, 실행 이력 관리, 의존성 설정 등 cron보다 풍부한 기능을 활용할 수 있습니다. 어느 방식을 쓰든 스크립트 내부에서 앞서 다룬 logging 모듈로 실행 시작/종료/에러를 남겨두어야 정기 실행 이력을 사후에 추적할 수 있습니다.
관련 개념 systemd .timer/.service, 가상환경 인터프리터 절대경로, journalctl 로그 조회
답안
API 키나 데이터베이스 비밀번호 같은 민감 정보를 소스 코드에 직접 하드코딩하면 버전 관리 시스템에 그대로 노출되어 심각한 보안 사고로 이어질 수 있으므로, 이런 값들은 코드와 분리해 환경변수(os.environ.get("API_KEY"))나 .env 파일(단, .gitignore에 반드시 등록), 또는 클라우드 환경의 시크릿 관리 서비스(예: 파라미터 스토어, 시크릿 매니저류)를 통해 실행 시점에 주입하는 것이 표준적인 방법입니다. 파이썬에서는 python-dotenv 같은 라이브러리로 .env 파일의 값을 환경변수처럼 로드해 쓸 수 있어 로컬 개발 편의성과 보안을 동시에 챙길 수 있습니다. 설정값이 환경(개발/스테이징/운영)마다 달라지는 경우에는 환경별로 별도의 설정 파일이나 네임스페이스를 두어 실수로 운영 환경 값이 다른 환경에 섞이지 않도록 관리하는 것도 중요합니다. 로깅 시에도 민감 정보가 로그에 그대로 찍히지 않도록 마스킹 처리하는 습관이 필요합니다.
관련 개념 .env / python-dotenv, .gitignore, 시크릿 매니저, 로그 마스킹
답안
threading 모듈은 하나의 프로세스 안에서 여러 스레드를 생성해 동시성을 구현하지만, 5단원에서 다룬 GIL의 제약으로 인해 한 순간에 하나의 스레드만 파이썬 코드를 실행할 수 있어 CPU 연산이 많은 작업에는 큰 성능 향상을 주지 못합니다. 대신 여러 서버에 순차적으로 SSH 접속하거나 다수의 API를 호출하는 것처럼 네트워크/디스크 I/O 대기 시간이 많은 작업에서는 대기 중 다른 스레드가 실행될 수 있어 threading만으로도 충분히 효과적인 성능 향상을 얻을 수 있습니다. multiprocessing 모듈은 여러 개의 독립된 파이썬 프로세스를 생성해 각자 별도의 GIL과 메모리 공간을 가지므로, 대량의 로그 파싱이나 데이터 변환처럼 CPU 연산이 많은 작업을 여러 CPU 코어에 분산시켜 실질적인 병렬 처리 성능을 얻을 수 있습니다. 다만 프로세스 간에는 메모리를 직접 공유할 수 없어 Queue나 Pipe 같은 별도의 IPC 메커니즘을 통해 데이터를 주고받아야 하고, 프로세스 생성 자체의 오버헤드가 스레드보다 크다는 점도 고려해야 합니다.
관련 개념 GIL 제약, I/O-bound vs CPU-bound 선택 기준, multiprocessing.Queue, concurrent.futures