리눅스에서 xargs 명령어를 알게 모르게 봤었는데요. 자주 보면서도 대체 왜 쓰는 것인지. 어떻게 동작하는지 잘 몰랐었습니다. 그래서 쓰게 되었습니다. 어떤 명령어인지만 간단하게 알아보겠습니다. 여기에서는 옵션들을 다루지 않습니다. 필요할 때 하나씩 익히도록 하겠습니다.

 


  먼저, xargs는 명령어를 만들고 실행시킨다고 되어 있습니다. stdio로부터. 표준 입력으로부터 읽어서 명령어를 만든 다음에, 해당 명령어를 수행하게끔 한다. 정도로 이해하면 됩니다.

 

 

 서문만 읽어보면, blank나 개행을 기준으로 토큰을 분리합니다. 그리고 command를 1번 혹은 그 이상 실행시킵니다. 어떤 것이랑 같이? initial arguments랑 같이. 표준 입력으로부터 읽은 것을 가지고 처리를 한다고 되어 있어요. 무슨 말인지 잘 모르겠네요. 그러니 한 번 실습해 보도록 하겠습니다.

 


 먼저, test 디렉토리에 1.txt를 생성합니다. 그리고 ls 명령어로 보면, 1.txt, test2.py, test.py가 있고 디렉토리 b, c가 있음을 알 수 있어요. 이제, echo "1.txt" | xargs rm을 입력해 보겠습니다.

 

 

 어? 그랬더니 1.txt가 사라졌습니다. 어떻게 된 일일까요? 먼저, echo "1.txt"의 결과를 개행이나 blank를 기준으로 분리를 합니다.

 

 그러면 위와 같이 분리가 됩니다. 이제 이것을 pipe로 넘겼으니, 1.txt라는 output이 xargs의 input으로 들어갑니다.

 

 xargs가 읽은 1.txt가 argument에 들어가게 됩니다. 사용법을 보면 xargs [options] [command [initial argument]]로 되어 있습니다. 여기서 이 initial argument가 1.txt가 됩니다. 실행되는 command는 rm이 되고요. 따라서, 해당 명령어는 rm 1.txt를 실행시키게 됩니다.

 


 다음에 1.txt와 2.txt를 xargs를 이용해서 삭제해 봅시다. touch 1.txt, touch 2.txt를 실행하였으므로, 1.txt와 2.txt가 실행될 겁니다. black.txt에는 1.txt, 2.txt가 한 줄에 하나씩 적혀있어요.

 

 

 이 상태에서 cat black.txt | xargs rm을 수행하면 어떻게 될까요? 결과부터 말씀드리면 1.txt와 2.txt가 제거됩니다. 어떻게 동작할까요? 간단한 테스트 프로그램을 만들어서 테스트 해 보도록 하겠습니다.

 

 

 black2.txt에는 위와 같은 내용들이 적혀져 있어요.

 

 다음에 이 파일은 인자의 수와 인자들을 출력해 주는 간단한 c 프로그램입니다. 파일명은 1.c이고 gcc -o 1 1.c로 컴파일 하였습니다.

 

 

 따라서, cat black2.txt | xargs ./1을 하면, ./1을 실행할 때 어떻게 인자를 받는지 알 수 있을 겁니다. 보니까, ./1 말고도 추가적으로 17개의 인자를 받네요. 고로 cat black.txt | xargs rm은 아래와 같이 동작합니다.

 

 1.txt, 2.txt를 공백 혹은 개행 문자를 기준으로 나눠버렸습니다. 그 결과 initial arguments에는 1.txt와 2.txt가 들어갑니다. 그래서, rm 1.txt 2.txt가 수행되는 것과 같은 결과를 내게 됩니다.

 

 


 다른 궁금증 하나. xargs가 command를 1번, 혹은 그 이상 실행 시킨다는 말은 어떤 말일까요? 어떨 때 2번 이상 실행될까요? 이것도 간단하게 확인해 봅시다.

 

 command.txt의 라인수는 10만입니다. 각 라인은 빈 문자열이 없습니다.

 

 1.c를 위와 같이 바꿔보겠습니다. 이것은 그냥 인자의 수만 출력합니다. 다음에 cat command.txt | xargs ./1을 실행시켜 봅시다.

 

 

 그러면 23697, 21845, 21845, 21845, 21773이 나오는데요. 이 5개의 수를 합하면 10만에, ./1이 실행된 횟수 5를 더한 값이 나옵니다. xargs는 ./1을 2번 이상 실행시켰습니다.

 


 이제, cat 명령어를 다시 보겠습니다. cat은 FILE이 없을 때, stdio에서 읽습니다.

 

 echo 3.txt | cat을 봅시다. 3.txt가 없었습니다. 그리고 echo 3.txt의 output이 cat의 input으로 들어가기 때문에, 3.txt가 출력되게 됩니다.

 

 반면에 이 경우는 조금 다릅니다. echo 3.txt | xargs cat인데요. echo 3.txt의 결과가 xargs cat의 입력으로 들어갑니다. 파일이 없었으니 그대로 "3.txt"가 들어갈 겁니다. xargs의 command는 cat이였습니다. 이 다음에 오는 argument가 3.txt였기 때문에, 실제로는 cat 3.txt가 수행되게 됩니다.

 

 그런데 파일이 없어요. 따라서, 3.txt가 없다는 에러 메세지가 출력되게 됩니다.