LFCS Linux 기초 실습
파일, 파이프, 텍스트 처리, 검색, 권한, 링크, 압축, 프로세스와 도움말을 직접 수행하는 기초 랩
이 실습은 Linux 기초를 실제 명령으로 확인한다.
/srv/lfcs-foundations만 사용하며 다른 경로는 삭제하지 않는다. 처음에는 풀이를 보며 수행하고, 환경을 초기화한 두 번째 시도부터는 문제만 보고 제한시간 안에 푼다.
작성·검증 상태: AI가 문제와 풀이 초안을 보조했다. destructive target은 전용 경로로 제한해 정적 검토했지만, 10개 문제 전체를 모든 지원 배포판에서 end-to-end 실행한 상태는 아니다.
실습 방식
각 문제를 다음 순서로 수행한다.
영문 task 읽기
→ 대상·동작·조건·지속성·검증 분해
→ 현재 상태 확인
→ 최소 변경
→ 완료 조건 검증
→ 풀이와 비교
풀이가 다른 명령이어도 요구된 최종 상태와 검증이 같으면 정답이 될 수 있다.
준비
root shell 또는 명령마다 sudo를 사용할 수 있는 실습 VM에서 실행한다.
install -d -o root -g root -m 0755 \
/srv/lfcs-foundations/input \
/srv/lfcs-foundations/work \
/srv/lfcs-foundations/restore
printf '%s\n' \
'2026-08-13T10:00:00Z INFO api started' \
'2026-08-13T10:01:00Z WARN disk usage=81 host=node1' \
'2026-08-13T10:02:00Z ERROR backend timeout host=node2' \
'2026-08-13T10:03:00Z INFO request status=200 host=node1' \
'2026-08-13T10:04:00Z ERROR permission denied host=node1' \
> /srv/lfcs-foundations/input/app.log
printf '%s\n' \
'alice:platform:active' \
'bob:operations:disabled' \
'carol:platform:active' \
'dave:security:active' \
> /srv/lfcs-foundations/input/users.txt
printf 'space in name\n' > '/srv/lfcs-foundations/input/report final.txt'
touch -d '10 days ago' /srv/lfcs-foundations/input/old.marker
기준 상태:
find /srv/lfcs-foundations -maxdepth 2 -printf '%M %u:%g %p\n'
문제 1 — 작업 위치와 command 확인 · 4분
English
Record the current user, host, working directory, login shell, and the source of the cd, ls, and systemctl commands in /srv/lfcs-foundations/work/context.txt. Do not assume that every command is an external executable.
완료 조건
- 실행 사용자, hostname, 현재 경로와 shell이 파일에 기록된다.
cd,ls,systemctl이 builtin·alias·file 중 무엇인지 확인할 수 있다.- command 조회 실패가 전체 기록을 중단시키지 않는다.
풀이 예시
{
printf 'user='; whoami
printf 'host='; hostname
printf 'pwd='; pwd
printf 'shell=%s\n' "$SHELL"
type -a cd
type -a ls
type -a systemctl
} > /srv/lfcs-foundations/work/context.txt 2>&1
cat /srv/lfcs-foundations/work/context.txt
type -a는 shell builtin·alias·함수·실행 파일을 함께 구분한다.
문제 2 — 파일, hard link와 symbolic link · 7분
English
Copy app.log to the work directory while preserving its metadata. Create a hard link named app.hard and a symbolic link named app.current. Remove only the copied pathname and prove which links still provide access to the data.
완료 조건
- 복사본과 hard link는 같은 inode를 사용한다.
- symbolic link는 복사본의 pathname을 가리킨다.
- 복사본 이름을 지운 뒤 hard link의 데이터는 남고 symbolic link는 dangling 상태가 된다.
풀이 예시
cp -a /srv/lfcs-foundations/input/app.log \
/srv/lfcs-foundations/work/app.copy
ln /srv/lfcs-foundations/work/app.copy \
/srv/lfcs-foundations/work/app.hard
ln -s app.copy /srv/lfcs-foundations/work/app.current
ls -li /srv/lfcs-foundations/work/app.*
stat -c '%i %h %n' /srv/lfcs-foundations/work/app.copy \
/srv/lfcs-foundations/work/app.hard
rm -- /srv/lfcs-foundations/work/app.copy
test -s /srv/lfcs-foundations/work/app.hard && echo 'hard link readable'
test -L /srv/lfcs-foundations/work/app.current && echo 'symlink exists'
test ! -e /srv/lfcs-foundations/work/app.current && echo 'symlink target missing'
-L은 symbolic link 자체를 확인하고 -e는 link가 가리키는 대상의 존재까지 본다.
문제 3 — stdout, stderr와 exit status · 6분
English
Run a command that writes normal to standard output, writes failed to standard error, and exits with status 7. Save the two streams in separate files and record the exit status without replacing it with the status of another command.
완료 조건
stdout.txt에는normal만 있다.stderr.txt에는failed만 있다.status.txt에는7이 기록된다.
풀이 예시
sh -c 'printf "normal\n"; printf "failed\n" >&2; exit 7' \
> /srv/lfcs-foundations/work/stdout.txt \
2> /srv/lfcs-foundations/work/stderr.txt
lfcs_status=$?
printf '%s\n' "$lfcs_status" > /srv/lfcs-foundations/work/status.txt
cat /srv/lfcs-foundations/work/stdout.txt
cat /srv/lfcs-foundations/work/stderr.txt
cat /srv/lfcs-foundations/work/status.txt
$?는 다음 command를 실행하면 즉시 바뀌므로 실패한 command 직후 저장한다.
문제 4 — 로그 검색과 집계 · 8분
English
From app.log, write only ERROR records to errors.txt. Then create error-host-count.txt containing each host and its ERROR count, sorted by the host name. Do not modify the source log.
완료 조건
- 정확히 두 ERROR 행만 추출된다.
- 결과는
node1 1,node2 1에 해당하는 집계를 포함한다. - source file의 checksum이 작업 전후 동일하다.
풀이 예시
sha256sum /srv/lfcs-foundations/input/app.log \
> /srv/lfcs-foundations/work/app.log.before.sha256
grep ' ERROR ' /srv/lfcs-foundations/input/app.log \
> /srv/lfcs-foundations/work/errors.txt
awk '/ ERROR / {
for (i=1; i<=NF; i++) {
if ($i ~ /^host=/) {
split($i, item, "=")
count[item[2]]++
}
}
}
END {
for (host in count) print host, count[host]
}' /srv/lfcs-foundations/input/app.log \
| sort > /srv/lfcs-foundations/work/error-host-count.txt
grep -c ' ERROR ' /srv/lfcs-foundations/work/errors.txt
cat /srv/lfcs-foundations/work/error-host-count.txt
sha256sum -c /srv/lfcs-foundations/work/app.log.before.sha256
awk의 배열로 host별 횟수를 세고 최종 출력은 sort에 맡겼다.
문제 5 — delimiter 데이터 필터링 · 7분
English
Read users.txt as colon-separated data. Write the names of active users in the platform team to active-platform-users.txt, sorted alphabetically. The output must contain names only.
완료 조건
- 결과는
alice,carol두 행이다. - 입력 순서와 관계없이 알파벳 순서다.
풀이 예시
awk -F: '$2 == "platform" && $3 == "active" {print $1}' \
/srv/lfcs-foundations/input/users.txt \
| sort > /srv/lfcs-foundations/work/active-platform-users.txt
cat /srv/lfcs-foundations/work/active-platform-users.txt
diff -u <(printf 'alice\ncarol\n') \
/srv/lfcs-foundations/work/active-platform-users.txt
process substitution <(...)은 Bash 기능이다. 검증에 사용했으며 실제 상태를 만드는 데 필수는 아니다.
문제 6 — 공백이 있는 파일을 안전하게 찾기 · 7분
English
Find every regular file directly under the input directory, including names containing spaces. Record each file’s mode, owner, group, size, and full pathname in input-files.txt. Do not cross into subdirectories.
완료 조건
report final.txt가 하나의 pathname으로 처리된다.- directory 자체나 하위 directory 내용은 포함되지 않는다.
- file name을 newline으로 나누어
xargs에 넘기지 않는다.
풀이 예시
find /srv/lfcs-foundations/input \
-maxdepth 1 -mindepth 1 -type f \
-exec stat -c '%A %U:%G %s %n' -- {} + \
> /srv/lfcs-foundations/work/input-files.txt
cat /srv/lfcs-foundations/work/input-files.txt
grep -F '/srv/lfcs-foundations/input/report final.txt' \
/srv/lfcs-foundations/work/input-files.txt
-exec ... {} +는 pathname을 별도 인자로 전달하므로 공백을 안전하게 처리한다.
문제 7 — group 공유 디렉터리와 umask · 9분
English
Create group lfcslab if it does not exist. Create /srv/lfcs-foundations/shared owned by root:lfcslab with mode 2770. Prove that a file created there with umask 0027 inherits the directory group and receives the expected mode. Do not change the system-wide umask.
완료 조건
- directory mode는
2770, owner는root:lfcslab이다. - 새 regular file의 group은
lfcslab이다. 0666에서 umask0027을 적용한 file mode를 설명할 수 있다.
풀이 예시
getent group lfcslab >/dev/null || groupadd lfcslab
install -d -o root -g lfcslab -m 2770 \
/srv/lfcs-foundations/shared
( umask 0027; touch /srv/lfcs-foundations/shared/example.txt )
stat -c '%A %a %U:%G %n' \
/srv/lfcs-foundations/shared \
/srv/lfcs-foundations/shared/example.txt
regular file은 기본적으로 실행 bit 없이 0666에서 시작하므로 0027을 적용하면 일반적인 결과는 0640이다. directory의 SGID가 group을 상속하지만 group write permission까지 강제로 상속하지는 않는다.
문제 8 — archive 생성과 시험 복원 · 8분
English
Create a gzip-compressed tar archive containing the input directory. Verify its member list, extract it under the restore directory, and compare every restored regular file with the source. Do not extract over the source tree.
완료 조건
- archive를 생성하고
tar목록 조회가 성공한다. - 별도 restore 경로에 해제한다.
- source와 restored tree의 file 내용 비교가 성공한다.
풀이 예시
tar -C /srv/lfcs-foundations \
-czf /srv/lfcs-foundations/work/input.tar.gz input
tar -tzf /srv/lfcs-foundations/work/input.tar.gz
rm -rf -- /srv/lfcs-foundations/restore/input
tar -C /srv/lfcs-foundations/restore \
-xzf /srv/lfcs-foundations/work/input.tar.gz
diff -r --no-dereference \
/srv/lfcs-foundations/input \
/srv/lfcs-foundations/restore/input
-C로 기준 디렉터리를 정하면 불필요한 상위 경로 없이 재현 가능한 archive를 만들 수 있다.
문제 9 — process 식별과 정상 종료 · 7분
English
Start a background sleep process for 600 seconds, record its PID, prove that the PID belongs to that command and current user, request graceful termination, and verify that it exited. Do not use killall or a broad name match.
완료 조건
- 시작한 정확한 PID만 대상으로 한다.
TERM을 먼저 사용한다.- 종료 뒤 같은 PID가 남지 않았음을 확인한다.
풀이 예시
sleep 600 &
lfcs_sleep_pid=$!
printf '%s\n' "$lfcs_sleep_pid" \
> /srv/lfcs-foundations/work/sleep.pid
ps -p "$lfcs_sleep_pid" -o pid,ppid,user,stat,etime,args
kill -TERM "$lfcs_sleep_pid"
wait "$lfcs_sleep_pid" 2>/dev/null || true
if ps -p "$lfcs_sleep_pid" >/dev/null 2>&1; then
echo 'process still exists'
else
echo 'process exited'
fi
이 실습은 자신이 시작한 process만 종료한다. 운영 service는 systemctl처럼 해당 service manager를 우선한다.
문제 10 — 로컬 문서만으로 옵션 찾기 · 8분
English
Using only locally installed help, identify: the find expression for staying on one filesystem, the tar option for listing an archive, the man-page section for /etc/fstab, and the systemd command used to validate a unit file. Record the commands and the relevant one-line evidence in local-doc-research.txt.
완료 조건
- 정답만 쓰지 않고 어디에서 찾았는지 command를 남긴다.
find,tar,fstab, systemd unit 검증을 모두 다룬다.- 인터넷 검색이나 개인 노트를 사용하지 않는다.
풀이 방향
{
printf '%s\n' '== find filesystem boundary =='
man find | col -b | grep -m1 -A2 -- '-xdev'
printf '%s\n' '== tar list option =='
tar --help | grep -m1 -E -- '--list|-t,'
printf '%s\n' '== fstab section =='
man -f fstab
printf '%s\n' '== systemd unit validation =='
systemd-analyze --help | grep -i verify
} > /srv/lfcs-foundations/work/local-doc-research.txt
cat /srv/lfcs-foundations/work/local-doc-research.txt
설치된 man database나 출력 형식에 따라 검색 행은 달라질 수 있다. 핵심은 man -k·man -f·--help에서 근거를 찾아 기록하는 것이다.
종합 채점
각 문제를 6점으로 채점한다.
| 항목 | 점수 |
|---|---|
| 정확한 대상 확인 | 1 |
| 요구 상태 생성 | 2 |
| 출력 또는 실제 동작 검증 | 1 |
| 기존 source 보존 | 1 |
| 제한시간 준수 | 1 |
다음 조건을 모두 만족하면 영역별 LFCS 실습으로 넘어간다.
- 10문제 중 8문제 이상을 풀이 없이 완료한다.
- 공백이 있는 pathname을 깨뜨리지 않는다.
- root에서 광범위한 wildcard·재귀 삭제를 사용하지 않는다.
- 실패한 command의 exit status와 stderr를 구분한다.
- 모르는 옵션 하나를 로컬 문서에서 2분 안에 찾는다.
초기화
정확한 대상인지 먼저 확인한다.
find /srv/lfcs-foundations -maxdepth 2 -printf '%M %u:%g %p\n'
이 실습 전용 경로만 삭제한다.
rm -rf -- /srv/lfcs-foundations
연습용 lfcslab group을 다른 실습에서 사용하지 않을 때만 삭제한다.
getent group lfcslab
groupdel lfcslab