리눅스 백그라운드 실행

LinuxBeginner
지금 연습하기

소개

리눅스는 강력한 프로세스 관리 기능을 제공하여 사용자가 터미널에서 계속 작업하면서 동시에 명령어를 백그라운드에서 실행할 수 있게 해줍니다. 이러한 기능은 지속적인 모니터링이 필요하지 않은 시간이 오래 걸리는 작업을 처리할 때 필수적입니다. 이 실습에서는 프로세스를 백그라운드에서 실행하고, 상태를 확인하며, 효과적으로 관리하는 방법을 배웁니다. 이러한 기술은 모든 리눅스 사용자에게 필수적이며 커맨드 라인 환경에서 작업할 때 더 큰 유연성을 제공합니다.

백그라운드 프로세스의 이해

리눅스에서 프로세스는 포그라운드 (Foreground) 또는 백그라운드 (Background) 에서 실행될 수 있습니다. 포그라운드 프로세스는 완료될 때까지 터미널을 점유하여 다른 명령어를 실행하지 못하게 합니다. 반면, 백그라운드 프로세스는 터미널을 차단하지 않고 실행되므로 커맨드 라인을 계속 사용할 수 있습니다.

먼저 시간이 오래 걸리는 작업을 시뮬레이션하는 간단한 스크립트를 만들어 보겠습니다. 이를 통해 백그라운드 프로세스를 시연해 볼 것입니다.

프로젝트 디렉토리로 이동합니다:

cd ~/project

nano 에디터를 사용하여 long-task.sh 파일을 생성합니다:

nano long-task.sh

파일에 다음 내용을 추가합니다:

#!/bin/bash
## This script simulates a long-running task
echo "Starting long task..."
for i in {1..20}; do
  echo "Processing step $i..."
  sleep 5
done
echo "Long task completed."

Ctrl+O를 누른 후 Enter 를 눌러 파일을 저장하고, Ctrl+X를 눌러 nano 를 종료합니다.

권한을 변경하여 스크립트를 실행 가능하게 만듭니다:

chmod +x long-task.sh

이제 스크립트를 포그라운드에서 실행해 봅니다:

./long-task.sh

스크립트가 5 초 간격으로 각 단계를 출력하는 것을 볼 수 있습니다. 이 동안에는 프로세스가 포그라운드에서 실행 중이므로 터미널에 다른 명령어를 입력할 수 없다는 점에 유의하세요.

스크립트가 완료되기 전에 Ctrl+C를 눌러 종료합니다.

백그라운드에서 프로세스 실행하기

프로세스를 백그라운드에서 실행하려면 명령어 끝에 앰퍼샌드 (&) 를 붙이기만 하면 됩니다. 이는 쉘에 해당 명령어를 백그라운드에서 실행하도록 지시합니다.

long-task.sh 스크립트를 백그라운드에서 실행해 보겠습니다:

cd ~/project
./long-task.sh &

다음과 유사한 출력이 나타날 것입니다:

[1] 1234
Starting long task...
Processing step 1...

여기서 [1]은 쉘이 할당한 작업 번호 (Job Number) 이고, 1234는 프로세스 ID(PID) 입니다. 작업 번호는 쉘 내부에서 이 백그라운드 프로세스를 참조할 때 사용되며, PID 는 운영체제가 프로세스를 식별하는 데 사용됩니다.

초기 출력 이후에 다시 명령 프롬프트가 나타나는 것을 확인하세요. 이제 스크립트가 백그라운드에서 실행되는 동안 다른 명령어를 계속 입력할 수 있습니다.

예를 들어, 다른 파일을 생성해 보세요:

echo "I can do other work while the script runs" > background-demo.txt
cat background-demo.txt

백그라운드 스크립트의 출력이 가끔씩 화면에 나타나더라도 터미널에서 계속 작업할 수 있음을 알 수 있습니다. 이는 터미널 세션을 차단하지 않고 시간이 많이 걸리는 작업을 실행할 때 매우 유용합니다.

중요 참고 사항: 백그라운드 프로세스의 출력이 터미널에 나타나는 것은 지극히 정상입니다. &를 사용하여 프로세스를 백그라운드로 실행하면 프로세스는 백그라운드에서 동작하지만, 출력 스트림 (stdout 및 stderr) 은 여전히 터미널에 연결되어 있습니다. 즉:

  • 프로세스는 백그라운드에서 실행 중입니다 (다른 명령어를 입력할 수 있음).
  • 프로세스는 터미널을 차단하지 않고 계속 실행됩니다.
  • 출력은 여전히 화면에 나타납니다 (다른 명령어와 섞일 수 있음).

이러한 동작은 의도된 것이며, 백그라운드 프로세스가 활발하게 실행되어 출력을 생성하고 있음을 보여줍니다.

백그라운드 프로세스 확인하기

리눅스는 백그라운드에서 실행 중인 프로세스를 확인하기 위한 여러 명령어를 제공합니다. 가장 일반적인 두 가지는 jobsps입니다.

jobs 명령어 사용하기

jobs 명령어는 현재 쉘 세션의 모든 백그라운드 작업 상태를 보여줍니다:

jobs

다음과 유사한 출력이 나타납니다:

[1]+  Running    ./long-task.sh &

+ 기호는 이것이 현재 기본 작업임을 나타내며, 작업 번호를 지정하지 않고 fgbg 같은 명령어를 사용할 때 대상이 됨을 의미합니다.

ps 명령어 사용하기

jobs는 현재 쉘에서 시작된 프로세스만 보여주는 반면, ps 명령어는 시스템에서 실행 중인 모든 프로세스를 보여줄 수 있습니다:

ps aux | grep long-task.sh

출력에는 백그라운드 스크립트에 대한 행이 포함되어야 합니다:

labex     1234  0.0  0.0   4508  1996 pts/0    S    12:34   0:00 /bin/bash ./long-task.sh

여러 작업을 확인하기 위해 또 다른 백그라운드 프로세스를 만들어 보겠습니다:

cd ~/project
nano another-task.sh

다음 내용을 추가합니다:

#!/bin/bash
## This script simulates another task
echo "Starting another task..."
for i in {1..20}; do
  echo "Another task - step $i..."
  sleep 5
done
echo "Another task completed."

저장 후 nano 를 종료하고 (Ctrl+O, Enter, Ctrl+X), 스크립트를 실행 가능하게 만듭니다:

chmod +x another-task.sh

이 스크립트도 백그라운드에서 실행합니다:

./another-task.sh &

이제 백그라운드 작업을 다시 확인해 보세요:

jobs

두 작업이 모두 목록에 나타날 것입니다:

[1]-  Running    ./long-task.sh &
[2]+  Running    ./another-task.sh &

백그라운드 프로세스 관리하기

이제 백그라운드에서 실행 중인 프로세스가 있으니, 이를 관리하는 방법을 배워보겠습니다. 리눅스는 백그라운드 프로세스를 제어하기 위한 몇 가지 명령어를 제공합니다.

백그라운드 프로세스를 포그라운드로 가져오기

fg 명령어는 백그라운드 프로세스를 포그라운드로 가져옵니다. 백그라운드 작업이 여러 개인 경우 작업 번호를 사용하여 특정 작업을 지정할 수 있습니다.

첫 번째 작업을 포그라운드로 가져와 보겠습니다:

fg %1

%1은 작업 번호 1 을 참조합니다. 이제 long-task.sh 스크립트의 출력이 터미널에 나타나며, 프로세스가 완료되거나 중단될 때까지 명령 프롬프트를 사용할 수 없게 됩니다.

프로세스를 중단하고 명령 프롬프트로 돌아가려면 Ctrl+C를 누르세요.

포그라운드 프로세스를 백그라운드로 보내기

포그라운드 프로세스를 백그라운드로 보낼 수도 있습니다. 먼저 Ctrl+Z로 포그라운드 프로세스를 일시 중지한 다음, bg 명령어를 사용하여 백그라운드에서 계속 실행하도록 합니다.

새로운 포그라운드 프로세스를 시작합니다:

cd ~/project
./long-task.sh

몇 초 후, Ctrl+Z를 눌러 프로세스를 일시 중지합니다. 다음과 같은 메시지가 나타납니다:

[1]+  Stopped    ./long-task.sh

이제 이를 백그라운드에서 재개합니다:

bg

프로세스가 백그라운드에서 다시 실행되며 다음이 표시됩니다:

[1]+ ./long-task.sh &

실행 중인지 확인해 보세요:

jobs

백그라운드 프로세스 종료하기

백그라운드 프로세스를 종료하려면 kill 명령어와 함께 작업 번호나 프로세스 ID 를 사용합니다:

kill %1

또는 PID 를 사용합니다 (ps 출력에서 확인한 실제 PID 로 1234 를 대체하세요):

kill 1234

프로세스가 종료되었는지 확인합니다:

jobs

작업이 종료되었음을 알리는 메시지가 표시될 수 있습니다:

[1]+  Terminated    ./long-task.sh

로그아웃 후에도 프로세스 유지하기

터미널에서 로그아웃한 후에도 프로세스가 계속 실행되어야 할 때가 있습니다. nohup 명령어는 쉘을 종료한 후에도 명령어가 계속 실행되도록 해줍니다.

오랫동안 실행될 스크립트를 만들어 보겠습니다:

cd ~/project
nano persistent-task.sh

다음 내용을 추가합니다:

#!/bin/bash
## This script runs for a very long time
echo "Starting persistent task at $(date)" > persistent-output.log
for i in {1..100}; do
  echo "Iteration $i at $(date)" >> persistent-output.log
  sleep 10
done
echo "Persistent task completed at $(date)" >> persistent-output.log

저장 후 nano 를 종료하고 스크립트를 실행 가능하게 만듭니다:

chmod +x persistent-task.sh

이제 nohup을 사용하여 백그라운드에서 실행합니다:

nohup ./persistent-task.sh &

다음과 유사한 출력이 나타납니다:

[1] 5678
nohup: ignoring input and appending output to 'nohup.out'

이는 프로세스가 백그라운드에서 실행 중이며 로그아웃하더라도 계속 유지됨을 의미합니다. 평소 터미널로 출력될 내용은 nohup.out이라는 파일로 리다이렉션됩니다.

출력 관리 팁: 백그라운드 프로세스의 출력이 터미널에 나타나 작업에 방해되는 것을 원치 않는다면 출력을 파일로 리다이렉션할 수 있습니다:

## 출력을 특정 파일로 리다이렉션
./long-task.sh > task-output.log 2>&1 &

## 또는 출력을 완전히 버리기 위해 /dev/null로 리다이렉션
./long-task.sh > /dev/null 2>&1 &

2>&1은 표준 출력 (stdout) 과 표준 에러 (stderr) 를 모두 리다이렉션합니다. 이렇게 하면 백그라운드 프로세스가 터미널을 어지럽히지 않고 조용히 실행됩니다.

프로세스가 실행 중인지 확인할 수 있습니다:

ps aux | grep persistent-task.sh

그리고 출력 파일을 살펴볼 수 있습니다:

cat persistent-output.log

출력에는 지속 작업의 시작 시간과 반복 횟수가 표시됩니다.

disown 명령어

로그아웃 후에도 프로세스를 유지하는 또 다른 방법은 disown 명령어를 사용하는 것입니다. 먼저 프로세스를 백그라운드에서 실행합니다:

cd ~/project
./persistent-task.sh &

그런 다음 disown을 사용하여 터미널과의 연결을 끊습니다:

disown %1

이제 터미널을 닫아도 이 프로세스는 계속 실행됩니다.

이러한 명령어들은 연결을 끊은 후에도 작업이 계속되어야 하는 원격 서버 작업 시 필수적입니다.

요약

이 실습에서는 백그라운드 프로세스 관리를 위한 필수적인 리눅스 기술을 배웠습니다. 다음 내용들을 실습했습니다:

  1. 포그라운드 및 백그라운드 모드에서 스크립트 생성 및 실행
  2. & 연산자를 사용하여 백그라운드에서 프로세스 실행
  3. jobsps 명령어를 사용하여 백그라운드 프로세스 상태 확인
  4. fgbg 명령어를 사용하여 프로세스를 포그라운드와 백그라운드 사이에서 전환 및 관리
  5. kill 명령어를 사용하여 백그라운드 프로세스 종료
  6. nohupdisown을 사용하여 로그아웃 후에도 유지되는 프로세스 실행

이러한 기술은 리눅스 환경에서 효율적으로 작업하기 위한 기초이며, 특히 시간이 오래 걸리는 작업을 처리하거나 원격 서버에서 작업할 때 중요합니다. 프로세스를 백그라운드에서 실행함으로써 터미널 세션을 차단하지 않고 여러 작업을 동시에 수행하여 생산성을 극대화할 수 있습니다.