Linux xargs 명령어: 명령어 빌드하기

LinuxBeginner
지금 연습하기

소개

이 실습에서는 Linux 의 강력한 xargs 명령어를 살펴봅니다. xargs 명령어는 표준 입력으로부터 명령어를 빌드하고 실행할 수 있게 해주는 다재다능한 도구입니다. 특히 인자 목록을 처리하여 명령줄로 변환하는 데 매우 유용합니다.

이 실습 전반에 걸쳐 "도서 처리"라는 개념을 예시 작업으로 사용합니다. 여기서 "도서 처리"는 특정 Linux 명령어가 아니라, 여러분이 항목 목록에 대해 수행하고자 하는 모든 작업을 대신하는 자리표시자임을 유의하세요. 예제에서는 이 처리를 시뮬레이션하기 위해 echotouch와 같은 간단한 명령어를 주로 사용할 것입니다. 실제 상황에서는 이를 여러분의 특정 작업에 맞는 더 복잡한 명령어 나 스크립트로 대체하여 사용하게 됩니다.

이 실습을 마치면 xargs를 사용하여 파일을 효율적으로 관리하고 반복적인 작업을 자동화할 수 있게 됩니다. 이 실습은 초보자를 위해 설계되었으므로 Linux 명령어가 생소하더라도 걱정하지 마세요. 각 단계를 차근차근 안내해 드립니다.

이것은 학습과 연습을 돕기 위해 단계별 지침을 제공하는 가이드 실습 (Guided Lab) 입니다. 각 단계를 완료하고 실무 경험을 쌓으려면 지침을 주의 깊게 따르십시오. 과거 데이터에 따르면 이 실습은 완료율 98%초급 수준 실습입니다. 학습자들로부터 98%의 긍정적인 평가를 받았습니다.

xargs 명령어 이해하기

먼저 xargs 명령어의 기본적인 사용법과 언제 이 도구가 유용한지 이해하는 것부터 시작해 보겠습니다. xargs는 한 명령어의 출력을 가져와서 다른 명령어의 인자로 사용해야 할 때 특히 유용합니다. 이는 쉘 스크립팅과 명령줄 워크플로우에서 흔히 발생하는 상황입니다.

항목 목록이 있고 각 항목에 대해 특정 동작을 수행하려는 시나리오를 생각해 보십시오. 스크립트에서 for 루프를 사용할 수도 있지만, 처리해야 할 목록이 방대하거나 대상 명령어가 여러 인자를 한꺼번에 처리할 수 있는 경우 xargs가 더 간결하고 효율적인 방법을 제공할 때가 많습니다.

파일의 입력을 사용하여 xargs가 어떻게 작동하는지 보여주는 간단한 예제를 살펴보겠습니다. 먼저 과일 목록이 포함된 파일의 내용을 확인해 봅니다.

cat ~/project/fruits.txt

다음과 같은 출력이 표시될 것입니다.

apple
orange
banana

이제 xargs를 사용하여 이 파일의 내용을 출력해 보겠습니다. 이는 파일의 각 줄을 가져와서 echo 명령어의 인자로 사용하는 과정을 시뮬레이션합니다.

cat ~/project/fruits.txt | xargs echo

다음과 같은 출력이 표시될 것입니다.

apple orange banana

이 예제에서 xargscat으로부터 입력 (파일의 각 줄) 을 받아 echo 명령어의 인자로 전달합니다. 여기서 echo 명령어는 우리의 "처리" 작업을 시뮬레이션하고 있습니다. 기본적으로 xargs는 각 줄을 별개의 인자로 취급하고 이를 하나의 명령어 실행으로 결합합니다.

여기서 일어나는 일을 분석해 보겠습니다.

  1. cat ~/project/fruits.txt가 파일의 내용을 읽습니다.
  2. | (파이프) 기호가 이 출력을 다음 명령어로 보냅니다.
  3. xargs echo가 입력받은 각 줄을 가져와 echo 명령어의 인자로 사용합니다.

이 방식이 유용한 이유는 단일 명령어로 여러 항목을 처리할 수 있기 때문입니다. 특히 대상 명령어가 여러 인자를 동시에 처리할 수 있는 경우, 각 항목을 따로 처리하는 것보다 훨씬 효율적입니다. 실제 응용 프로그램에서는 echo를 목록의 각 항목에 대해 실행해야 하는 실제 명령어 나 스크립트로 바꾸면 됩니다. 이것이 바로 xargs가 빛을 발하는 지점입니다. 즉, 목록을 생성하는 명령어와 인자를 기반으로 작동하는 명령어 사이의 가교 역할을 합니다.

xargs 로 파일 처리하기

xargs가 입력을 받아 인자로 사용하는 방식을 바탕으로, 좀 더 실용적인 응용 사례인 파일 처리를 살펴보겠습니다. 여러분이 디지털 아카이브를 정리하는 사서라고 가정해 보십시오. 도서 제목 목록이 있고, 각 도서에 대한 빈 파일을 생성해야 합니다. 간단한 for 루프를 사용할 수도 있지만, 파일 목록이 다른 명령어 (예: find) 에 의해 생성되는 경우 xargs가 훌륭한 대안이 됩니다.

xargs를 사용하여 목록으로부터 파일을 생성하는 과정을 자동화해 보겠습니다. 먼저 도서 제목이 포함된 파일의 내용을 확인합니다.

cat ~/project/books.txt

다음과 같이 표시됩니다.

The_Great_Gatsby
To_Kill_a_Mockingbird
1984

이제 xargstouch 명령어를 사용하여 각 도서에 대한 빈 파일을 생성해 보겠습니다. 여기서는 -I 옵션을 도입할 것인데, 이 옵션은 실행될 명령어 내의 특정 위치에 입력 인자를 배치해야 할 때 매우 중요합니다.

cat ~/project/books.txt | xargs -I {} touch ~/project/{}.txt

이 명령어를 분석해 보겠습니다.

  • cat ~/project/books.txt: 도서 목록 파일의 내용을 읽습니다.
  • |: 파이프 기호가 cat의 출력을 다음 명령어로 보냅니다.
  • xargs: 표준 입력으로부터 명령어를 빌드하고 실행하는 명령어입니다.
  • -I {}: 이 옵션은 명령어 내에서 {}가 나타나는 부분을 각 입력 줄로 교체하도록 xargs에 지시합니다. 이는 실행하려는 명령어의 중간이나 끝부분에 입력 인자가 들어가야 할 때 (단순히 끝에 추가하는 것이 아닐 때) 특히 유용합니다.
  • touch ~/project/{}.txt: xargs가 각 입력 줄에 대해 실행할 명령어입니다. {}는 각 도서 제목으로 교체되며, 파일명을 만들기 위해 .txt가 뒤에 붙습니다.

이 명령어는 -I {} 옵션을 사용하여 각 입력 항목에 대한 자리표시자 ({}) 를 지정합니다. books.txt의 각 줄에 대해 xargs{}를 도서 제목으로 바꾸고 touch 명령어를 실행하여, 결과적으로 도서 제목 뒤에 .txt 확장자가 붙은 파일을 생성합니다.

파일이 생성되었는지 확인해 봅시다.

ls ~/project/*.txt

다음과 같은 출력이 표시되어야 합니다.

/home/labex/project/1984.txt
/home/labex/project/The_Great_Gatsby.txt
/home/labex/project/To_Kill_a_Mockingbird.txt
/home/labex/project/books.txt
/home/labex/project/fruits.txt

보시다시피 xargs는 각 도서 제목에 대해 새로운 .txt 파일을 생성했으며, 기존의 books.txtfruits.txt 파일도 함께 있습니다. 이는 xargs가 항목 목록에 명령어를 적용하는 데 어떻게 사용될 수 있는지 보여주며, 파일 조작 및 자동화를 위한 강력한 도구임을 증명합니다.

xargs 로 인자 개수 제한하기

디지털 라이브러리가 커짐에 따라, 실행하려는 명령어가 수용할 수 있는 인자 수에 제한이 있거나, 더 나은 제어 및 리소스 관리를 위해 항목을 작은 단위로 나누어 처리하고 싶은 상황이 생길 수 있습니다. xargs-n 옵션을 사용하면 각 명령어 실행에 전달되는 인자의 개수를 제한할 수 있습니다. 이는 입력을 기반으로 명령어가 실행되는 방식을 xargs가 세밀하게 제어할 수 있는 또 다른 시나리오입니다.

더 많은 도서 제목이 들어 있는 파일을 확인해 봅시다.

cat ~/project/more_books.txt

다음과 같이 표시됩니다.

Pride_and_Prejudice
The_Catcher_in_the_Rye
The_Hobbit
Animal_Farm
Brave_New_World

이제 -n 옵션과 함께 xargs를 사용하여 한 번에 두 권의 책을 처리해 보겠습니다. 처리되는 단위를 시각적으로 확인하기 위해 다시 echo를 사용합니다.

cat ~/project/more_books.txt | xargs -n 2 echo "Processing books:"

다음과 유사한 출력이 표시될 것입니다.

Processing books: Pride_and_Prejudice The_Catcher_in_the_Rye
Processing books: The_Hobbit Animal_Farm
Processing books: Brave_New_World

여기서 일어나는 일을 분석해 보겠습니다.

  • cat ~/project/more_books.txt: 도서 목록 파일의 내용을 읽습니다.
  • |: 파이프 기호가 cat의 출력을 다음 명령어로 보냅니다.
  • xargs -n 2: 각 명령어 실행 시 최대 2 개의 인자만 사용하도록 xargs에 지시합니다. 즉, xargs는 입력 줄을 두 개씩 그룹화하여 각 그룹에 대해 대상 명령어를 실행합니다.
  • echo "Processing books:": xargs가 실행할 명령어입니다. 인자 (도서 제목들) 가 이 명령어 뒤에 추가됩니다.

이 명령어는 도서를 두 권씩 짝지어 처리하며, 제목 개수가 홀수인 경우 마지막 도서는 단독으로 처리됩니다. -n 옵션은 항목을 특정 그룹 크기로 처리하고 싶을 때 유용하며, 이는 대규모 목록을 관리하거나 인자 수 제한이 있는 명령어를 다룰 때 도움이 됩니다. 큰 작업을 동일한 명령어로 실행되는 더 작고 관리하기 쉬운 하위 작업으로 나누는 방법을 제공합니다.

xargs 를 이용한 병렬 처리

라이브러리가 계속 확장됨에 따라 파일 처리 속도를 높이고 싶을 것입니다. 서로 독립적인 작업의 경우, 병렬로 실행하면 전체 실행 시간을 크게 단축할 수 있습니다. xargs-P 옵션을 사용하면 대상 명령어의 인스턴스를 여러 개 동시에 실행할 수 있으며, 이는 I/O 바운드 작업이나 대기 시간이 포함된 작업의 성능을 크게 향상시킵니다. 이것이 단순한 순차적 for 루프 처리와 비교했을 때 xargs가 갖는 핵심적인 장점입니다.

먼저, 도서 내용에 타임스탬프를 추가하고 지연 시간을 도입하여 도서 처리를 시뮬레이션하는 스크립트를 만들어 보겠습니다. 이 지연 시간은 병렬 실행을 시각적으로 확인하는 데 도움이 됩니다.

cat ~/project/process_book.sh

내용은 다음과 같습니다.

#!/bin/bash
echo "Processing $1 at $(date)" > ~/project/processed_$1
sleep 2 ## 처리 시간을 시뮬레이션하기 위한 대기

이 스크립트는 다음을 수행합니다.

  1. 도서 제목을 인자 ($1) 로 받습니다.
  2. 도서 제목 앞에 "processed_"가 붙은 새 파일을 생성합니다.
  3. 현재 날짜와 시간을 포함한 메시지를 이 파일에 기록합니다.
  4. 병렬 실행을 더 명확하게 확인할 수 있도록 2 초 동안 대기하며 처리 시간을 시뮬레이션합니다.

이제 -P 옵션과 함께 xargs를 사용하여 도서를 병렬로 처리해 보겠습니다. 또한 각 도서 제목을 스크립트의 인자로 전달하기 위해 다시 -I 옵션을 사용합니다.

cat ~/project/more_books.txt | xargs -P 3 -I {} ~/project/process_book.sh {}

이 명령어를 분석해 보겠습니다.

  • cat ~/project/more_books.txt: 도서 목록을 읽습니다.
  • |: 출력을 xargs로 보냅니다.
  • xargs -P 3: 최대 3 개의 프로세스를 병렬로 실행하도록 xargs에 지시합니다. xargs는 대상 명령어의 인스턴스를 동시에 최대 3 개까지 실행하며, 각 인스턴스는 하나 이상의 입력 항목을 처리합니다.
  • -I {}: 각 입력 항목에 대한 자리표시자로 {}를 정의하며, 이는 스크립트의 인자로 전달됩니다.
  • ~/project/process_book.sh {}: 각 도서에 대해 실행할 명령어이며, {}는 도서 제목으로 교체됩니다.

이 명령어는 최대 3 권의 도서를 동시에 처리하기 시작합니다. 명령어를 실행한 후 처리된 파일의 내용을 확인할 수 있습니다.

cat ~/project/processed_*

도서들이 거의 동시에 또는 약간의 시간 차이를 두고 처리된 것을 보여주는 출력이 표시될 것이며, 이는 병렬 실행을 의미합니다. 정확한 시간은 다를 수 있지만 다음과 같이 표시될 수 있습니다.

Processing Pride_and_Prejudice at Mon Aug 12 10:15:01 UTC 2024
Processing The_Catcher_in_the_Rye at Mon Aug 12 10:15:01 UTC 2024
Processing The_Hobbit at Mon Aug 12 10:15:01 UTC 2024
Processing Animal_Farm at Mon Aug 12 10:15:03 UTC 2024
Processing Brave_New_World at Mon Aug 12 10:15:03 UTC 2024

처음 세 권의 도서가 같은 시간에 처리를 시작하고, 마지막 두 권은 약 2 초 후에 시작되는 것을 확인하십시오 (스크립트의 sleep 2 때문입니다). 이는 병렬 처리가 실제로 작동하고 있음을 보여주며, 독립적인 작업의 속도를 높이는 데 xargs를 사용하는 큰 이점입니다.

xargs 옵션 조합하기

실제 상황에서는 원하는 처리 방식을 구현하기 위해 여러 xargs 옵션을 조합해야 하는 경우가 많습니다. 마지막 작업으로, 병렬 처리를 활용하면서 도서를 묶음 (batch) 단위로 처리하는 방법을 살펴보겠습니다. 단순한 명령어에 -n-I 옵션을 직접 사용할 때 발생하는 상호 배타적 문제를 피하기 위해 약간 다른 접근 방식을 사용하겠습니다. 대신 xargs의 대상으로 쉘 명령어 (sh -c) 를 사용하여, -n에 의해 전달된 여러 인자를 쉘 스크립트 내에서 처리하도록 할 것입니다.

고전 도서 목록을 확인해 봅시다.

cat ~/project/classic_books.txt

다음과 같이 표시됩니다.

Moby_Dick
War_and_Peace
Ulysses
Don_Quixote
The_Odyssey
Madame_Bovary
Lolita
Hamlet
The_Iliad
Crime_and_Punishment

이제 xargs를 사용하여 이 도서들을 2 권씩 묶어서 처리하되, 최대 3 개의 병렬 프로세스를 사용해 보겠습니다. 처리 중인 묶음을 출력하는 간단한 명령어를 실행하기 위해 sh -c를 사용합니다.

cat ~/project/classic_books.txt | xargs -n 2 -P 3 sh -c 'echo "Processing batch: $@"' _

이 명령어를 분석해 보겠습니다.

  • cat ~/project/classic_books.txt: 고전 도서 목록을 읽습니다.
  • |: 출력을 xargs로 보냅니다.
  • xargs: 표준 입력으로부터 명령어를 빌드하고 실행하는 명령어입니다.
  • -n 2: 각 명령어 실행 시 2 개의 인자 (도서 제목) 를 사용하도록 지시합니다. 이 두 인자는 sh -c 명령어에 전달됩니다.
  • -P 3: 최대 3 개의 프로세스를 병렬로 실행하도록 지시합니다. 각 프로세스는 2 권의 도서 묶음을 가지고 sh -c 명령어를 실행합니다.
  • sh -c 'echo "Processing batch: $@"' _: xargs가 실행할 명령어입니다.
    • sh -c: 쉘을 사용하여 명령어 문자열을 실행합니다.
    • 'echo "Processing batch: $@"': 실행할 명령어 문자열입니다. 쉘 스크립트 내의 $@는 스크립트에 전달된 모든 위치 매개변수로 확장되며, 이 경우 xargs가 제공한 두 개의 인자 (도서 제목) 가 됩니다.
    • _: sh -c에 전달되는 더미 (dummy) 인자입니다. 이는 쉘 스크립트 내에서 $0의 값이 됩니다. sh -c$0이 설정되기를 기대하므로 이를 사용하며, $@를 사용할 때 출력에는 영향을 주지 않습니다.

다음과 유사한 출력이 표시될 것입니다.

Processing batch: Moby_Dick War_and_Peace
Processing batch: Ulysses Don_Quixote
Processing batch: The_Odyssey Madame_Bovary
Processing batch: Lolita Hamlet
Processing batch: The_Iliad Crime_and_Punishment

이 명령어는 병렬 처리의 이점을 누리면서도 방대한 항목을 묶음 단위로 효율적으로 처리하는 방법을 보여줍니다. 이 경우 도서를 두 권씩 짝지어 처리하고 (-n 2), 이러한 2 인 1 조 처리 명령어를 최대 3 개까지 병렬로 실행하고 있습니다 (-P 3).

이 방식의 장점은 항목을 관리 가능한 덩어리 (이 경우 도서 두 권씩) 로 처리하면서도, 병렬 처리를 통해 전체 작업 속도를 높일 수 있다는 것입니다. 이는 대규모 데이터셋을 다루거나 처리 속도와 시스템 리소스 사용량 사이의 균형을 맞춰야 할 때 특히 유용합니다. sh -c를 사용함으로써 단일 명령어 실행 내에서 -n으로 전달된 여러 인자를 효과적으로 처리할 수 있으며, 이는 xargs를 복잡한 처리 워크플로우를 위한 유연한 도구로 만들어 줍니다. 실제 상황에서는 echo 명령어를 항목 묶음을 처리하도록 설계된 더 복잡한 처리 스크립트로 대체할 수 있습니다.

요약

이 실습에서는 xargs 명령어를 사용하여 파일 관리 작업을 자동화하는 방법을 배웠습니다. 기본적인 사용법부터 파일 처리, 인자 제한, 병렬 처리, 그리고 효율적인 묶음 처리를 위한 옵션 조합까지 살펴보았습니다. 이러한 기술은 Linux 환경에서 대량의 데이터를 처리하거나 반복적인 작업을 자동화해야 할 때 매우 유용할 것입니다.

실습에서 다루지 않은 몇 가지 추가적인 xargs 옵션은 다음과 같습니다.

  • -0: 공백 대신 널 (null) 문자를 구분자로 사용
  • -L: 명령줄당 최대 지정된 수의 비어 있지 않은 입력 줄 사용
  • -s: 명령줄당 최대 지정된 수의 문자 사용
  • -r: 표준 입력이 비어 있으면 명령어를 실행하지 않음
  • -a: 표준 입력 대신 파일에서 항목을 읽음
  • -E: EOF(파일 끝) 문자열 설정

xargs의 진정한 힘은 유연성과 다른 Linux 명령어와의 연동 능력에서 나옵니다. Linux 를 계속 사용하다 보면 xargs가 작업을 자동화하고 생산성을 높이는 데 도움이 되는 더 많은 상황을 발견하게 될 것입니다.