기본 문법
명령 | xargs [옵션] [실행할명령 [초기인자...]]
xargs는 표준 입력으로 들어온 내용을 공백이나 개행 단위로 잘라, 지정한 명령의 인자(argument)로 붙여서 실행하는 명령어입니다. find나 grep, ls 같은 명령은 결과를 출력할 뿐 다른 명령을 대신 실행해 주지 않으므로, 그 결과를 chmod·rm·cp 같은 명령에 넘겨 처리하려면 중간 다리가 필요합니다. xargs가 그 역할을 합니다.
또한 xargs는 인자를 한 번에 전달하지 않고 시스템이 허용하는 명령행 길이에 맞춰 여러 번 나누어 실행합니다. 그래서 파일이 많은 디렉터리에서도 "인자 목록이 너무 김(Argument list too long)" 오류를 피할 수 있습니다. -n, -I, -0 같은 옵션으로 한 번에 넘길 인자 개수와 위치, 구분자를 조절합니다.
실무에서는 로그 파일 권한 일괄 변경(#157), 오래된 백업 정리(#189), 특정 문자열을 포함한 파일만 골라 처리하는 작업에 쓰입니다. 자격시험에서도 find와 결합한 형태, 공백이 포함된 파일명을 안전하게 처리하는 `find -print0 | xargs -0` 조합이 자주 다뤄집니다.
자주 쓰는 옵션
| 옵션 | 의미 | 예 |
|---|---|---|
-n N | 한 번 실행할 때 넘길 인자 개수를 최대 N개로 제한 | seq 1 6 | xargs -n 2 echo |
-I 문자열 | 인자가 들어갈 자리를 지정. -L 1이 함께 적용되어 입력 한 줄당 한 번 실행 | ls *.log | xargs -I {} mv {} {}.old |
-0 | 입력 구분자를 널 문자로 처리(공백·개행이 포함된 파일명에 안전) | find . -type f -print0 | xargs -0 chmod 640 |
-d 구분자 | 입력 구분자를 지정한 문자로 변경(이때 개행은 구분자가 아닌 일반 문자로 취급됨) | printf 'a,b,c' | xargs -d , echo |
-p | 각 명령 실행 전 실행 여부를 묻는 대화형 모드 | ls | xargs -p rm |
-t | 실행할 명령을 표준 오류로 먼저 출력 | ls *.txt | xargs -t wc -l |
-r, --no-run-if-empty | 입력이 비어 있으면 명령을 실행하지 않음(GNU 확장) | grep -l TODO *.txt | xargs -r rm |
-L N | 입력 N줄을 한 번의 실행 인자로 사용 | cat list.txt | xargs -L 1 echo |
-a 파일 | 표준 입력 대신 지정한 파일에서 인자를 읽음 | xargs -a list.txt echo |
-P N | 최대 N개의 프로세스를 병렬로 실행(-n 또는 -L과 함께 사용) | cat list.txt | xargs -P 4 -n 1 gzip |
실무 예시
인자를 개수로 나눠 실행
$ seq 1 6 | xargs -n 2 echo 묶음:
묶음: 1 2
묶음: 3 4
묶음: 5 6
-n 2로 인자를 2개씩 나눠 echo를 세 번 실행합니다. xargs가 입력을 여러 번의 실행으로 분할하는 기본 동작을 확인할 수 있습니다.
find 결과의 파일 권한 일괄 변경
준비: mkdir -p /tmp/demo/logs; cd /tmp/demo/logs; touch app.log audit.log error.log readme.txt; chmod 666 *.log; chmod 644 readme.txt
$ find /tmp/demo/logs -maxdepth 1 -name '*.log' -print0 | xargs -0 chmod 640 && ls -l /tmp/demo/logs
total 0
-rw-r-----. 1 root root 0 Sep 16 11:49 app.log
-rw-r-----. 1 root root 0 Sep 16 11:49 audit.log
-rw-r-----. 1 root root 0 Sep 16 11:49 error.log
-rw-r--r--. 1 root root 0 Sep 16 11:49 readme.txt
*.log 파일만 640으로 바꾸고 readme.txt는 644를 유지합니다. -print0과 -0을 함께 써서 파일명에 공백이 있어도 안전합니다. 권한 표시 끝의 점(.)은 SELinux 컨텍스트가 있다는 표시이며, ls -l 첫 줄의 total 0도 함께 출력됩니다.
-I로 인자 위치 지정하기
준비: mkdir -p /tmp/demo/rename; cd /tmp/demo/rename; touch a.txt b.txt c.txt
$ cd /tmp/demo/rename && ls *.txt | xargs -I {} mv {} {}.bak && ls
a.txt.bak
b.txt.bak
c.txt.bak
-I {}를 쓰면 인자가 {} 자리에 들어가 입력 한 줄당 한 번씩 실행됩니다. 인자를 명령 중간에 두어야 하는 mv, cp에 유용합니다. 다만 ls의 출력을 파이프로 넘기는 방식은 파일명에 공백이나 개행이 있으면 깨지므로, 실제 운영 환경에서는 find -print0 | xargs -0 -I {} 형태를 권장합니다.
오래된 백업만 삭제(최신 3개 유지)
준비: mkdir -p /tmp/demo/rotatelab; cd /tmp/demo/rotatelab; for d in 0901 0902 0903 0904 0905; do touch backup_$d.tar.gz; done
$ cd /tmp/demo/rotatelab && ls -1 backup_*.tar.gz | sort -r | tail -n +4 | xargs -r rm -f && ls
backup_0903.tar.gz
backup_0904.tar.gz
backup_0905.tar.gz
이름을 역순 정렬해 최신 3개를 제외한 나머지를 xargs로 rm에 넘깁니다. -r은 삭제 대상이 없을 때 rm이 인자 없이 실행되는 것을 막습니다. 파일명 규칙이 날짜순 정렬과 일치할 때만 올바르게 동작하므로, 실제 적용 전에는 rm -f 대신 echo로 먼저 대상 목록을 확인하고 cd로 작업 디렉터리를 반드시 한정하세요.
내용으로 파일을 골라 처리하기
준비: mkdir -p /tmp/demo/src; cd /tmp/demo/src; echo 'TODO: fix' > a.txt; echo 'done' > b.txt; echo 'TODO: later' > c.txt
$ cd /tmp/demo/src && grep -l TODO *.txt | xargs -t chmod 600
chmod 600 a.txt c.txt
grep -l로 문자열을 포함한 파일 목록만 뽑아 chmod에 전달합니다. chmod 자체는 출력이 없고, 화면에 보이는 줄은 -t 옵션이 표준 오류로 출력한 실행 명령입니다.
주의할 점
- 파일명에 공백이나 개행이 있으면 기본 구분자 때문에 인자가 잘립니다. find -print0 | xargs -0 조합을 쓰세요.
- 입력이 비어 있어도 GNU xargs는 기본적으로 명령을 한 번 실행합니다. rm처럼 영향이 큰 명령에는 -r을 붙이세요.
- -I를 쓰면 -L 1이 함께 적용되어 입력 한 줄마다 프로세스가 생성되므로, 대량 작업에서는 -0으로 여러 인자를 묶어 넘기는 편이 빠릅니다.
- find -exec와 역할이 겹칩니다. find 결과만 처리한다면 -exec ... + 가 간단하고, 다른 명령의 파이프 출력을 받을 때 xargs가 필요합니다.
- chmod·rm 등 되돌리기 어려운 명령을 넘길 때는 먼저 xargs echo나 -p로 대상 목록을 확인하고, 작업 경로를 좁게 지정하세요.
이 명령어로 풀 수 있는 실습 문제
브라우저 웹 터미널에서 바로 풀고 요구사항별로 자동 채점됩니다. 로그인 없이 5분 체험도 가능합니다.
관련 명령어
마지막 검수 2026-09-16 · 내용에 오류가 있으면 문제 페이지의 질문 기능으로 알려 주세요.
