Overview
xargs 명령어에 대해서 알아보자.
xargs란?
xargs는 표준 입력으로부터 데이터를 받아서, 그 데이터를 명령어의 인자로 전달하는 유닉스 및 리눅스 명령어 유틸리티이다.
일반적으로 xargs는 파이프(|)를 사용하여 다른 명령어의 출력을 입력으로 받는다. 이렇게 함으로써, xargs는 하나의 명령어가 처리할 수 있는 것보다 더 많은 양의 데이터를 처리할 수 있게 해준다.
xargs의 주요 사용 사례 중 하나는 `find, grep, ls` 등의 명령어로부터 나온 많은 수의 파일명이나 데이터를 다른 명령어에 전달할 때이다. 예를 들어, 특정 유형의 파일을 찾아서 모두 삭제하거나, 편집하고 싶을 때 xargs를 사용할 수 있다.
사용법
1. find
find . -name '*.txt' | xargs rm
- 이 명령어는 현재 디렉토리에서 .txt로 끝나는 모든 파일을 찾아서 `(find . -name '*.txt')` 그 파일들을 삭제하는 예시이다.
`xargs`는 다음과 같은 옵션들을 가질 수 있다.
- -n [수]: 한 번에 전달할 인자의 수를 지정합니다. 예를 들어, `-n 1` 옵션을 사용하면 각 파일명을 개별적으로 처리합니다.
- -I [치환자]: 입력되는 각 항목을 명령어의 특정 위치에 치환하여 사용할 수 있게 해준다. 예를 들어, `-I {}` 옵션을 사용하면 `{}`를 입력 항목으로 치환할 수 있다.
- -0 또는 -null: 입력 항목이 널 문자`(\0)`로 구분되어 있음을 지정한다. 이 옵션은 파일명에 공백이나 특수 문자가 포함된 경우 유용하다.
2. ls
현재 디렉토리에 있는 모든 `.log` 파일을 찾아서 삭제하는 예시이다.
ls *.log | xargs rm
- `ls`로 `.log` 파일을 나열하고, `xargs`를 통해 `rm` 명령으로 전달하여 파일을 삭제한다.
3. find
특정 패턴에 맞는 파일을 찾아서 해당 파일들에 대한 작업을 수행하는 예시이다.
find . -type f -name "*.txt" -print0 | xargs -0 wc -l
- `find`로 현재 디렉토리 및 하위 디렉토리에서 `.txt` 확장자를 가진 파일을 찾고, `xargs -0`를 통해 `wc -l` 명령으로 전달하여 각 파일의 라인 수를 계산한다.
4. 표준입력
표준 입력으로부터 받은 데이터를 인자로 사용하여 명령어를 여러 번 실행하는 예시이다.
echo "one two three" | xargs -n 1 echo "Word:"
- "one", "two", "three" 각각에 대해 "Word:"를 접두어로 붙여서 세 번 echo를 실행한다.
5. kubectl
`kubectl` 명령어에도 적용할 수 있다. 특정 네임스페이스의 `Error, Evicted, CrashLoopBackOff` 상태의 Pod를 전부 제거하는 예시이다.
Error
kubectl get po -n <namespace> | grep Error | awk '{print $1}' | xargs kubectl delete po -n <namespace>
Evicted
kubectl get po -n <namespace> | grep Evicted | awk '{print $1}' | xargs kubectl delete po -n <namespace>
CrashLoopBackOff
kubectl get po -n <namespace> | grep CrashLoopBackOff | awk '{print $1}' | xargs kubectl delete po -n <namespace>
6. docker
docker 명령어에도 동일하게 적용 가능하다. `Exit`된 컨테이너를 전부 삭제하는 예시이다.
sudo docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs sudo docker rm
- 이 밖에도 모든 명령어와 결합하여 다양한 사용이 가능하다.
7. 사용법 활용(Calling another Bash shell with xargs compiled input)
명령어 스트링은 현재 디렉토리에 있는 특정 패턴을 가진 서브 디렉토리(이 경우엔 00, 01, 02, ... 10과 같은)에서 `file.txt` 파일을 찾아, 그 내용을 상위 디렉토리의 `total_file.txt` 파일에 추가하는 데 사용된다.
mkdir 00 01 02 03 04 05 06 07 08 09 10
ls
00 01 02 03 04 05 06 07 08 09 10
echo 'a' > 03/file.txt
echo 'b' > 07/file.txt
echo 'c' > 10/file.txt
# echo로 명령어 확인
ls -d --color=never [0-9][0-9] | xargs -I{} echo 'cd {}; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi'
cd 00; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 01; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 02; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 03; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 04; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 05; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 06; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 07; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 08; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 09; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
cd 10; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi
# 실행
ls -d --color=never [0-9][0-9] | xargs -I{} sh -c 'cd {} && if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi'
# 실행2
ls -d --color=never [0-9][0-9] | xargs -I{} echo 'cd {}; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi' | xargs -I{} bash -c "{}"
ls
00 01 02 03 04 05 06 07 08 09 10 total_file.txt
cat total_file.txt
a
b
c
echo로 명령어 확인 설명
- 디렉토리 목록 생성
- ls -d --color=never [0-9][0-9]: 이 명령은 현재 디렉토리에서 "00", "01", "02", ..., "10"과 같은 이름 패턴을 가진 모든 디렉토리를 나열한다. `-d` 옵션은 디렉토리 자체를 나열하며, `-color=never` 옵션은 출력에서 색상을 제거한다.
- xargs를 사용하여 각 디렉토리에 대한 명령 실행
- xargs -I{}: `xargs`는 표준 입력으로부터 데이터를 받아 이를 명령어의 인자로 사용한다. `-I{}` 옵션은 `{}`가 나타나는 곳에 입력 데이터를 대체한다.
- 각 디렉토리에서 조건부 명령 실행
- echo 'cd {}; if [ -r ./file.txt ]; then cat file.txt >> ../total_file.txt; fi': 이 부분은 각 디렉토리로 이동`(cd {})`하고, 현재 디렉토리에 `file.txt` 파일이 읽기 가능`(-r)`한지 확인한다.
- 만약 파일이 존재하고 읽기 가능하다면, `cat file.txt >> ../total_file.txt` 명령을 사용하여 파일의 내용을 상위 디렉토리의 `total_file.txt` 파일 끝에 추가한다.
8. 사용법 활용(Multi-threaded xargs)
명령어들은 랜덤 시간 동안 대기`(sleep)`한 후 "Done!" 메시지를 출력하는 예제이다. 두 명령어 간의 주요 차이점은 `xargs` 명령어에 `-P` 옵션의 사용 유무이다.
1) 첫번째 명령어
time for i in $(seq 1 5); do echo $[$RANDOM % 5 + 1]; done | xargs -I{} echo "sleep {}; echo 'Done! {}'" | xargs -I{} bash -c "{}"
Done! 4
Done! 3
Done! 4
Done! 2
Done! 3
real 0m16.034s
user 0m0.033s
sys 0m0.005s
- 이 명령어는 각 반복마다 랜덤한 시간(1~5초) 동안 대기`(sleep)`하고, 대기가 끝난 후 "Done!" 메시지와 함께 대기 시간을 출력한다.
- 이 과정은 순차적으로 실행되며, 각 `sleep` 명령이 완료된 후 다음 명령이 실행된다.
2) 두번째 명령어
time for i in $(seq 1 5); do echo $[$RANDOM % 5 + 1]; done | xargs -I{} echo "sleep {}; echo 'Done! {}'" | xargs -P5 -I{} bash -c "{}"
Done! 1
Done! 1
Done! 2
Done! 4
Done! 4
real 0m4.007s
user 0m0.016s
sys 0m0.003s
- 두 번째 명령어는 `-P5` 옵션을 사용하여 최대 5개의 프로세스를 병렬로 실행한다. 이는 각 `sleep` 명령이 동시에 실행되며, 따라서 전체 실행 시간이 줄어든다.
- 랜덤 시간 대기 후에 출력되는 "Done!" 메시지의 순서도 랜덤하게 된다.
실행 시간 비교
- 첫 번째 명령어는 모든 명령이 순차적으로 실행되기 때문에 총 실행 시간이 더 길어진다. 예를 들어, 각 명령이 평균적으로 3초씩 걸린다면 총 실행 시간은 약 15초가 된다.
- 두 번째 명령어는 명령이 동시에 실행되므로 총 실행 시간이 대폭 줄어든다. 이 경우, 가장 긴 대기 시간을 가진 명령이 완료될 때까지의 시간이 전체 실행 시간이 된다. 예를 들어, 가장 긴 대기 시간이 5초라면 총 실행 시간은 약 5초가 된다.
결과적으로, 두 번째 명령어는 첫 번째 명령어에 비해 실행 시간이 훨씬 짧다.
Reference
https://en.wikipedia.org/wiki/Xargs
https://linuxconfig.org/multi-threaded-xargs-with-examples
'Linux' 카테고리의 다른 글
리눅스 명령어 3. sed, awk란? (0) | 2024.01.20 |
---|---|
리눅스 명령어 2. jq란? (2) | 2024.01.19 |
Chattr 이란? (0) | 2022.07.25 |
CentOS 7 / 계정에 sudo 권한 주기 (0) | 2022.04.28 |
Django(Linux) (0) | 2022.02.16 |