이 글에서는 리눅스(Ubuntu 포함) 셸에서 명령어를 백그라운드로 실행하는 방법을 소개합니다. 특히 SSH로 원격 서버에 접속해 작업할 때 매우 유용한 기능입니다.
SSH를 통해 원격 컴퓨터에 접속한 상태에서 오래 걸리는 작업을 실행해야 한다고 가정해 봅시다.
일반적으로 작업이 진행되는 동안에는 터미널 창과 연결을 계속 열어두어야 합니다. 하지만 다른 작업을 위해 창을 닫아야 하거나, 인터넷 연결이 불안정해서 언제든 끊길 수 있는 상황이라면 상당히 번거롭습니다.
창이 닫히거나 연결이 끊기면 원격 컴퓨터에서 실행 중이던 명령어도 중단될 수 있습니다.
명령어를 백그라운드로 실행하면 이런 문제를 피할 수 있습니다. 연결이나 세션이 유지되는지와 관계없이 작업은 계속 실행됩니다.
또한 스크립트 작성 시에도 유용합니다. 어떤 명령어를 실행하되 그 결과가 완료될 때까지 기다릴 필요가 없고, 이후 출력값을 사용할 필요도 없다면 백그라운드 실행이 적합합니다.
& 기호로 명령어를 백그라운드에서 실행하기
리눅스에서 명령어를 백그라운드로 실행하는 방법은 아주 간단합니다. 명령어 끝에 & 문자만 붙이면 됩니다.
your_command_here &
예를 들어 다음 명령어는 두 개의 파일을 압축하는 작업입니다. 백그라운드에서 실행되므로 작업이 완료될 때까지 기다리지 않고 바로 다른 명령어를 입력할 수 있습니다.
zip archive.zip file1 file2 &
정말 간단하죠? 실행 결과는 대략 다음과 같이 표시됩니다.
[1] 3001
여기서 [1]은 작업(job) 번호, 3001은 백그라운드에서 실행 중인 프로세스 ID(PID)를 의미합니다.
작업이 완료되면(또는 실패하면) 해당 상태가 출력됩니다.
[1] + done zip archive.zip file1 file2
백그라운드 작업의 출력 숨기기
명령어가 백그라운드에서 실행되는 동안에도 출력 결과는 계속 터미널에 표시됩니다.
이 출력이 다른 작업에 방해가 된다면 표준 리디렉션(standard redirection)을 사용해 숨길 수 있습니다.
your_command > /dev/null 2>&1 &
- 위 명령어에서 >는 명령어의 STDOUT(표준 출력)을 /dev/null로 리디렉션합니다.
- 2>&1은 STDERR(표준 에러 출력)을 STDOUT으로 보내며, 결과적으로 에러 메시지 역시 /dev/null로 전달됩니다.
- /dev/null은 출력이 어디에도 저장되지 않는 특수 장치입니다. 즉, 출력은 사라지고 아무 곳에도 남지 않습니다.
실행 중인 백그라운드 작업 목록 확인하기
현재 실행 중인 백그라운드 작업 목록을 확인하려면 jobs 명령어를 사용합니다.
jobs -l
실행 중인 백그라운드 작업 목록이 표시되며, 각 항목은 다음과 같은 형태입니다.
[1] + 3601 running ping 8.8.8.8 > /dev/null 2>&1
위 예시에서 ping 8.8.8.8 > /dev/null 2>&1 명령어가 작업 번호 1, 프로세스 ID 3601로 백그라운드에서 실행 중임을 확인할 수 있습니다.
백그라운드 작업 중지하기
kill 명령어를 사용하면 실행 중인 작업을 중지할 수 있습니다.
kill 3601
백그라운드 작업의 프로세스 ID를 지정하면 해당 프로세스가 종료(kill)됩니다.
세션이 끊겨도 백그라운드 작업 유지하기
아마도 가장 실용적인 부분입니다.
창을 닫거나 연결이 끊기거나 세션이 어떤 이유로든 중단되더라도 명령어가 계속 실행되게 하려면 disown 명령어로 백그라운드 작업을 분리(disown)해야 합니다.
disown %1
위 명령어는 작업 번호가 1인 백그라운드 작업을 분리합니다. 분리된 작업은 현재 셸과의 연결이 끊기며, 완료되거나 오류가 발생하거나 KILL 명령으로 종료될 때까지 계속 실행됩니다.
모든 실행 중인 프로세스를 확인하는 방법을 다룬 글도 참고해 보세요. disown으로 분리한 작업을 추적해야 할 때 필요할 수 있습니다.
실행 중인 명령어를 백그라운드로 옮기기
이미 실행 중인 명령어를 백그라운드로 옮기려면 먼저 일시 중지(suspend)한 뒤 백그라운드로 전환해야 합니다.
명령어가 실행되는 동안 CTRL + Z를 누르면 다음과 같은 메시지가 표시됩니다.
suspended command_name
명령어가 일시 중지되었음을 확인할 수 있습니다.
이제 bg 명령어를 입력하면 해당 명령어가 백그라운드에서 계속 실행됩니다.
bg
다음과 같은 메시지가 표시됩니다.
continued command_name
명령어가 이제 백그라운드에서 정상적으로 실행되고 있음을 확인할 수 있습니다.