fg 명령어의 슈퍼 팁 : Ctrl+Z가 터미널 세션을 저장할 때
게시: 18 April 2026
당신은 던집니다`./gradlew build`, 터미널이 3분 동안 차단되며, 다른 일을 해야 대기 중 인가요? 새 탭을 열 필요가 없습니다.`Ctrl+Z`프로세스를 일시 중지하고,`fg`그곳으로 정확히 데려다 놓습니다. 이는 개발자의 일상에서 가장 과소평가되는 유닉스 팁입니다.
- 틱
-
[]
문제 : 바쁜 터미널
모든 개발자는 이런 상황을 겪었습니다 :
$ ./gradlew build
> Building...
터미널이 잠겼습니다. 더 이상 명령을 입력할 수 없습니다. 파일을 확인하고 실행해야 할`git status`, 또는 점유된 포트를 확인하세요.
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "터미널" as term participant "Gradle (프로세스)" as gradle dev -> term : ./gradlew build term -> gradle : Lance le build gradle -> term : Occupe le terminal\n(pas de prompt) dev -> term : veut taper une commande term --> dev : ❌ Terminal bloqué note right of dev Le développeur est paralysé pendant toute la durée du build end note @enduml
대부분의 개발자들은 새로운 터미널을 엽니다. 하지만 더 우아하고, 더 빠르고, 네이티브한 해결책이 있습니다: 작업 관리
세 가지 필수 명령어
Ctrl+Z — 일시 중지 (SIGTSTP)
`Ctrl+Z`신호를 보냅니다`SIGTSTP`포그라운드 프로세스에. 프로세스는중단된— 죽지 않은 — 그리고 터미널이 프롬프트를 되찾는다.
$ ./gradlew build
> Building...
^Z
[1]+ Stoppé ./gradlew build
$
대괄호 안의 숫자`[1]`(two spaces)잡 번호. Le `+`기본 작업을 나타냅니다.
fg — 앞으로 가져오기
`fg`일시 정지된 작업을 포그라운드로 가져옵니다. 프로세스는 정확히 중지된 지점에서 다시 시작됩니다.
$ fg
./gradlew build
> Building... (reprend où il en était)
특정 작업 번호:
$ fg %2
bg — 백그라운드에서 재개
`bg`프로세스를 sans 블로킹하지 않고 계속 진행하세요. 긴 빌드에 적합합니다.
$ bg
[1]+ ./gradlew build &
$
Le `&`마지막에 그것은 프로세스가 백그라운드에서 실행 중임을 의미합니다.
jobs — 셸의 작업 목록 보기
$ jobs
[1]- Stoppé vim README.md
[2]+ En cours ./gradlew build
@startuml skinparam backgroundColor #FEFEFE skinparam defaultFontName sans-serif state "전경\n(차단된 터미널)" as fg #LightCoral state "일시 중지됨\n(Ctrl+Z)" as stopped #LightYellow state "배경\n(bg)" as bg_ #LightGreen [*] --> fg : Lance une commande fg --> stopped : Ctrl+Z\n(SIGTSTP) stopped --> fg : fg\nreprend en avant-plan stopped --> bg_ : bg\nreprend en arrière-plan bg_ --> fg : fg\nramène en avant-plan fg --> [*] : Commande terminée note right of stopped Le processus est figé mais _pas_ tué end note note left of bg_ Le terminal est libre le build continue end note @enduml
시나리오 1 : 긴 빌드
이는 가장 일반적인 사용 사례입니다. Gradle 빌드를 실행하면 터미널이 막히고 다른 작업을 해야 합니다.
@startuml skinparam backgroundColor #FEFEFE autonumber actor Développeur as dev participant "터미널" as term participant "Gradle" as gradle database "상태\n프로세스" as state dev -> term : ./gradlew build term -> gradle : Lance le build gradle -> state : En cours (FG) dev -> term : Ctrl+Z term -> state : Suspendu (job [1]) term --> dev : Prompt libre $ dev -> term : git status term --> dev : working tree clean dev -> term : fg term -> state : Reprend (FG) gradle --> dev : Build réussi ✓ note right of state Le processus Gradle n'a jamais été tué Il reprend exactement où il s'était arrêté end note @enduml
한 걸음씩
$ ./gradlew build
> Building...
^Z
[1]+ Stoppé ./gradlew build
$ git status
On branch main
nothing to commit, working tree clean
$ fg
./gradlew build
> Building...
BUILD SUCCESSFUL in 2m 34s
시나리오 2 : 잊어버린 편집자
당신은 안에 있습니다`vim`, 다른 파일을 sans 떠나지 않고 확인해야 합니다`vim`.
# Dans vim, en mode commande :
:shell
$ cat /path/to/other/file.txt
$ exit
# Retour dans vim
하지만 그것은 무겁다. 그리고`Ctrl+Z`, 즉시적입니다 :
# Dans vim, n'importe quel moment :
Ctrl+Z
[1]+ Stoppé vim README.md
$ cat /path/to/other/file.txt
# ... lire le fichier ...
$ fg
vim README.md
# Retour exact là où on en était, curseur en place
@startuml skinparam backgroundColor #FEFEFE autonumber actor Développeur as dev participant "vim" as vim participant "껍질" as shell dev -> vim : édition en cours dev -> vim : Ctrl+Z vim -> shell : Suspendu (job [1]) dev -> shell : cat autre_fichier.txt shell --> dev : contenu du fichier dev -> shell : fg shell -> vim : Reprend (job [1]) vim --> dev : Curseur exactement\nà la même position note right of vim vim restaure intégralement l'état : position du curseur, buffer, undo stack end note @enduml
참고:`vim`완벽하게 그 상태를 복구한 후`fg`: 커서 위치, 버퍼 내용, 실행 취소 기록 — 전부 보존됩니다.
시나리오 3: opencode 프로세스가 일시 중지됨
이 기사를 쓰게 된 계기는 이 시나리오입니다. 당신은 사용하고 있습니다.opencode(코드에서 LLM을 실행하기 위한 CLI 툴), 그리고 프로세스가 중지됩니다.
@startuml skinparam backgroundColor #FEFEFE skinparam defaultFontName sans-serif skinparam componentStyle rectangle actor Développeur as dev participant "opencode (LLM 에이전트)" as agent participant "껍질" as shell participant "깃" as git dev -> agent : Session active agent -> agent : Tour de parole\ndu LLM en cours note over agent Ctrl+Z arrive en plein milieu d'une analyse de code end note dev -> agent : Ctrl+Z agent -> shell : Suspendu (job [1]) dev -> git : git diff git --> dev : changements visibles dev -> shell : fg shell -> agent : Reprend (job [1]) agent --> dev : Reprend exactement\nl'analyse en cours note right of agent Aucune perte de contexte Le LLM reprend sa réponse exactement où il en était end note @enduml
$ opencode
# ... session en cours, LLM analyse le code ...
^Z
[1]+ Stoppé opencode
$ git diff HEAD~1
# vérifier les changements récents
$ fg
opencode
# Le LLM reprend là où il s'était arrêté
장점은 두 배입니다:
-
컨텍스트 손실 없음: LLM 세션, 대화 기록, 열린 파일 — 모든 것이 보존됩니다
-
재시작 없음opencode를 재시작할 필요 없고, 컨텍스트를 재로드할 필요 없고, LLM에게 문제를 다시 설명할 필요 없어
시나리오 4 : 여러 작업을 동시에 관리하기
fg et `bg`여러 개가 일시 중지된 상태에서 특정 프로세스를 대상으로 작업 번호를 받아들입니다.
$ vim config.yml
^Z
[1]+ Stoppé vim config.yml
$ ./gradlew test
^Z
[2]+ Stoppé ./gradlew test
$ htop
^Z
[3]+ Stoppé htop
$ jobs
[1] Stoppé vim config.yml
[2]- Stoppé ./gradlew test
[3]+ Stoppé htop
$ fg %2
./gradlew test
# Le build reprend en avant-plan
$ bg %3
[3] htop &
# htop reprend en arrière-plan
@startuml
skinparam backgroundColor #FEFEFE
rectangle "중지된 작업" as jobs #LightYellow {
card "[1] vim config.yml" as j1
card "[2] ./gradlew test" as j2
card "[3] htop" as j3
}
rectangle "행동" as actions #LightGreen {
card "fg %2
→ 전경" as a1
card "bg %3\n→ 배경" as a2
card "fg %1
→ 전경" as a3
}
jobs --> actions : fg/bg + numéro de job
actions --> j2 : Reprend
actions --> j3 : En arrière-plan
note bottom of jobs
Chaque job conserve
son état exact
entre les suspend/resume
end note
@enduml
작업 명령어 요약
| 주문 | 효과 | 예시 |
|---|---|---|
|
전경 프로세스를 일시 중지합니다 |
전송`SIGTSTP` |
|
기본 작업을 포그라운드에서 재개합니다. |
|
|
작업 n을 전경에서 재개 |
|
|
백그라운드에서 기본 작업 재개 |
|
|
백그라운드에서 작업 n을 다시 시작 |
|
|
현재 쉘의 작업 목록을 나열 |
|
|
작업 n 종료 |
|
fg, bg, Ctrl+Z, Ctrl+C 및 &의 차이
많은 개발자들이 이러한 메커니즘을 혼동합니다. 이것이 결정적인 명확화입니다.
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultFontName sans-serif
rectangle "**Ctrl+Z**\nSIGTSTP" as ctrlz #LightYellow {
card "프로세스를 일시 중지
(메모리에 여전히 존재)
fg/bg와 함께 사용 가능" as c1
}
rectangle "**Ctrl+C**\nSIGINT" as ctrlc #LightCoral {
card "프로세스를 죽여
(돌아갈 수 없습니다)
상태 전체 손실" as c2
}
rectangle "**& **\n(배경)" as ampersand #LightGreen {
card "직접 실행
백그라운드에서
터미널을 즉시 자유롭게" as c3
}
rectangle "**fg**
(전경)" as fg_ #SkyBlue {
card "일시 정지된 작업을 전경으로 가져와
터미널이 사용 중" as c4
}
rectangle "**bg**\n(배경)" as bg_ #Lavender {
card "작업을 재개합니다\n백그라운드에서 일시 중지된\n터미널 사용 가능" as c5
}
ctrlz -right-> fg_ : fg pour reprendre
ctrlz -right-> bg_ : bg pour continuer\nen arrière-plan
ctrlc -right-> c2 : Pas de retour\nprocessus tué
note bottom of ctrlz
Le processus est **figé**
mais **pas tué**
end note
note bottom of ampersand
Alternative : lancer
./gradlew build &
directement en arrière-plan
end note
@enduml
| 단축키/명령 | 신호 | 효과 | 뒤로 가시겠어요? |
|---|---|---|---|
|
|
프로세스를 일시 중지 (메모리 내에 고정된, 동결된) |
네 :`fg` ou |
|
|
프로세스를 죽이세요 (완료됨) |
아니요 : 파괴된 프로세스 |
|
|
프로세스를 죽이고 + 코어 덤프 |
아니요: 프로세스가 파괴되었습니다. |
|
— |
백그라운드에서 바로 실행 |
`fg`앞으로 가져오기 위해 |
Ctrl+Z`이다비파괴적. 프로세스는 그대로 메모리에서 정지됩니다. 당신은 즉시 이어서 할 수 있습니다.`fg. 이것은 _pause_일 뿐, _stop_이 아닙니다.
|
작업의 전체 수명 주기
@startuml skinparam backgroundColor #FEFEFE skinparam defaultFontName sans-serif title 셸 작업의 전체 생명 주기 state "존재하지 않는" as none state "전경 (터미널 점유 중)" as foreground #LightCoral state "일시 정지됨 (Ctrl+Z / SIGTSTP)" as suspended #LightYellow state "배경\n(bg ou &)" as background #LightGreen state "완료 (exit code 0)" as done #LightGray [*] --> none none --> foreground : tape une commande foreground --> suspended : Ctrl+Z foreground --> done : fin normale suspended --> foreground : fg suspended --> background : bg suspended --> done : kill %n background --> foreground : fg background --> done : fin normale\n(en arrière-plan) background --> suspended : Ctrl+Z\n(si fg puis Ctrl+Z) done --> [*] note right of suspended L'état suspendu est le pivot de tout le système de jobs end note @enduml
고급 팁
fg와 가장 최근의 직업 및 교대
fg`인수 없이 표시된 작업을 되돌린다.+(가장 최신). 하지만 또한 사용할 수 있습니다%-`이전 작업을 대상으로 지정하려면 :
$ vim file1.txt
^Z
[1]+ Stoppé vim file1.txt
$ vim file2.txt
^Z
[2]+ Stoppé vim file2.txt
$ fg # ramène job [2] (le plus récent)
$ fg %- # ramène job [1] (le précédent)
작업을 깔끔하게 종료하다
$ jobs
[1]- Stoppé vim config.yml
[2]+ Stoppé ./gradlew test
$ kill %2 # envoie SIGTERM au job 2
$ kill -9 %1 # envoie SIGKILL au job 1 (force)
disown : 쉘에서 분리
disown`쉘의 작업 테이블에서 작업을 제거합니다. 프로세스는 계속 실행되지만 더 이상 불러올 수 없습니다.`fg:
$ ./gradlew build &
[1] 12345
$ disown %1
# Le processus continue mais n'est plus lié au shell
# Ça survives à la fermeture du terminal
nohup과 결합하여 긴 프로세스를 실행
터미널이 종료될 때 프로세스가 살아남게 하려면 :
$ nohup ./gradlew build &
[1] 12345
$ disown %1
# Le build continue même si vous fermez le terminal
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultFontName sans-serif
rectangle "fg" as fg_ #SkyBlue {
card "일을 가져와라\n가장 최근의 (+)" as f1
card "특정 직업 대상
특정 : fg %n" as f2
card "교대로 : fg %-" as f3
}
rectangle "kill %n" as kill_ #LightCoral {
card "SIGTERM (정상)" as k1
card "SIGKILL -9 (강제)" as k2
}
rectangle "거부하다" as disown #Lavender {
card "쉘에서 분리
(연결 해제 후에도 살아남음)" as d1
}
rectangle "nohup + &" as nohup_ #LightGreen {
card "면역된 프로세스
SIGHUP에 대한
(터미널 종료 시 살아남음
터미널)" as n1
}
fg_ -right-> kill_ : si faut\nterminer
kill_ -right-> disown_ : ou détacher
nohup_ -left-> fg_ : fg ramène en\navant-plan
note bottom of disown_
Après disown, fg ne peut
plus ramener le job
end note
@enduml
함정과 일반적인 오류
Ctrl+Z와 Ctrl+C를 혼동하다
가장 흔한 실수입니다.`Ctrl+C`프로세스를 죽입니다.`Ctrl+Z`그를 중단합니다. 만약 당신이 누르면`Ctrl+C`반사적으로, 전체 상태가 손실됩니다 — 열린 파일, LLM 세션, 진행 중인 빌드.
@startuml
skinparam backgroundColor #FEFEFE
rectangle "Ctrl+Z (SIGTSTP)" as z #LightGreen {
card "메모리에서 고정된 프로세스" as z1
card "fg 그를 무사히 데려온다" as z2
card "손실 없음" as z3
}
rectangle "Ctrl+C (SIGINT)" as c #LightCoral {
card "프로세스 완료" as c1
card "영구적으로 손실된 상태" as c2
card "돌이킬 수 없습니다" as c3
}
note bottom of z
Pause → Reprendre
end note
note bottom of c
Kill → Perdu
end note
@enduml
작업은 셸에 국한됩니다.
jobs, fg et `bg`다른 터미널을 열면 다른 터미널의 작업을 볼 수 없습니다.
# Terminal 1
$ vim file.txt
^Z
[1]+ Stoppé vim file.txt
# Terminal 2 (nouveau)
$ jobs
# (rien — les jobs sont locaux au shell)
시스템 전체 프로세스를 보려면`ps` ou htop:
ps aux | grep vim
작업은 셸이 닫히면 생존하지 못합니다.
터미널을 닫으면 일시 중지된 작업 또는 백그라운드 작업이 모두 삭제됩니다. 프로세스가 살아남으려면 사용`nohup`+disown:
$ nohup ./gradlew build &
[1] 12345
$ disown %1
# Fermer le terminal → le build continue
대화형 프로세스와 fg
일부 대화형 프로그램은 한 이후에 잘 작동하지 않는다`Ctrl+Z`+fg. 드문하지만 발생한다 :
-
신호를 사용하는 일부 프로그램(vim, htop, less)은 잘 처리합니다.
Ctrl+Z) -
장시간 실행되는 네트워크 프로그램(ssh, opencode)은 일반적으로 정상적으로 복구됩니다.
-
터미널을 수정하는 프로그램(ncurses)은 때때로 터미널을 예기치 않은 상태로 남겨둘 수 있다
터미널이 손상된 후`fg`, 입력 :
reset
요약 다이어그램
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultFontName sans-serif
skinparam ArrowColor #444444
title "fg — 모든 것을 바꾸는 팁"
rectangle "문제" as problem #LightCoral {
card "터미널 차단됨\n프로세스에 의해" as p1
card "새로운\n터미널 열기 = 무거운 해결책" as p2
}
rectangle "**해결책**" as solution #LightGreen {
card "Ctrl+Z → 일시 정지" as s1
card "fg → 다시 이어간다" as s2
card "배경에서" as s3
card "jobs → 정지된 것 보기" as s4
}
rectangle "장점" as advantages #SkyBlue {
card "맥락 손실 없음" as a1
card "재시작하지 마세요" as a2
card "터미널 하나면 충분합니다." as a3
}
problem -right-> solution : "네이티브 솔루션
40년 된 유닉스"
solution -right-> advantages : "결과"
note bottom of advantages
fg n'est pas un tips obscur
C'est un mécanisme fondamental
du shell Unix
end note
@enduml
왜 fg가 과소평가되는가?
대부분의 현대 개발자들은 발견합니다`fg`늦거나, 전혀 이루어지지 않을 수도 있습니다. 몇 가지 이유 :
-
IDE는 터미널을 숨깁니다.: VS Code는 내장 터미널을 제공하지만, 여러 탭이`fg`겉으로는 덜 필요함
-
그래픽 도구가 CLI를 대체합니다: 파일 관리자, 시스템 모니터, 그래픽 Git 클라이언트
-
tmux와 스크린: 이 멀티플렉서는 같은 문제를 다르게 해결하지만`fg`더 간단하고 항상 사용 가능합니다
그런데,`fg`는 :
-
보편적인POSIX 셸 모두에 존재 (bash, zsh, fish…)
-
의존 없이tmux 또는 screen을 설치할 필요가 없습니다
-
스냅샷: 두 번의 타격 (
Ctrl+Z`그리고`fg) 일시 중지 및 재개를 위해 -
컨텍스트 보존자: 프로세스의 상태는 무결합니다
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultFontName sans-serif
rectangle "왜 fg가
과소 평가됩니까?" as why #LightCoral {
card "IDE와 터미널
다중 탭" as w1
card "그래픽 도구\nCLI를 대체하는" as w2
card "tmux/screen
문제를 해결합니다
다른 방식으로" as w3
}
rectangle "왜 fg 이다\n더 우월한 ?" as superior #LightGreen {
card "범용: bash,
zsh, fish, sh..." as s1
card "의존성 없음:
설치 필요 없음" as s2
card "두 번의 타격:\nCtrl+Z 그리고 fg" as s3
card "보존된 컨텍스트 :\n상태 손실 없음" as s4
}
why -right-> superior : "간단함
항상 이긴다"
@enduml
기술 메모리 : 신호
호기심을 가진 사람들을 위해, 관련된 신호는 다음과 같습니다:
| 신호 | 이름 | 보낸 사람 | 효과 |
|---|---|---|---|
2 |
|
|
중단 — 프로세스를 종료합니다 |
3 |
|
|
코어 덤프와 함께 종료 |
18 |
|
|
대화형 정지 — 프로세스 일시 정지 |
19 |
|
|
계속 — 일시 중지된 프로세스를 재개한다 |
15 |
|
|
깨끗한 종료 |
9 |
|
|
강제 종료 (차단할 수 없음) |
전체 흐름 :
@startuml skinparam backgroundColor #FEFEFE skinparam defaultFontName sans-serif participant "사용자" as user participant "쉘" as shell participant "프로세스" as proc user -> shell : Ctrl+Z shell -> proc : SIGTSTP (signal 18) note right of proc : Processus figé\nen mémoire user -> shell : fg shell -> proc : SIGCONT (signal 19) note right of proc : Processus reprend\nen avant-plan user -> shell : bg shell -> proc : SIGCONT (signal 19) note right of proc : Processus reprend\nen arrière-plan user -> shell : Ctrl+C shell -> proc : SIGINT (signal 2) note right of proc : Processus terminé\nétat perdu @enduml
결론
`fg`이것은 obscure한 팁이 아니라, 1970년대부터 사용 가능한 Unix 셸의 기본 메커니즘입니다. 대부분의 개발자들이 이를 모른다는 사실은 우리의 시대를 보여주는 증상입니다: IDE와 멀티플렉서가 우리에게 기본으로부터 멀어지게 만들었습니다.
하지만 SSH 서버에 접속해 있거나, 최소한의 터미널을 사용 중이거나, 단순히 사용 중인 경우`opencode`그리고 LLM은 한창 작업 중입니다 —Ctrl+Z, fg, bg, `jobs`votre 가장 친한 친구들이에요.
_ Ctrl+Z 일시정지, fg 재개. 터미널의 일시정지-재생입니다. _
참고문헌
-
man bash— 섹션 JOB CONTROL -
man signal— POSIX 신호 목록
관련 기사
31 May 2026
14 May 2026