왜 xargs가 필요한가?


25

"notes.txt"라는 파일을 제외한 디렉토리의 모든 파일을 제거한다고 가정합니다. 나는 이것을 파이프 라인으로 할 것이다 ls | grep -v "notes.txt" | xargs rm. 두 번째 파이프의 출력이 rm이 사용해야하는 입력 인 경우 왜 xargs가 필요합니까?

비교를 위해 파이프 라인 echo "#include <knowledge.h>" | cat > foo.c은 xargs를 사용하지 않고 에코 된 텍스트를 파일에 삽입합니다. 이 두 파이프 라인의 차이점은 무엇입니까?


3
ls | grep -v "notes.txt" | xargs rm제외하고 notes.txt는 일반적으로 출력을 구문 분석하지 않는ls 모든 것을 제거 하는 데 사용해서는 안됩니다 . 예를 들어 단일 파일에 공백이 있으면 명령이 중단됩니다. 더 안전한 방법은 rm !(notes.txt)Bash ( shopt -s extglob세트) 또는 rm ^notes.txtZsh (with EXTENDED_GLOB) 등입니다.
slhck

공백을 피하기 위해 :-) find . -maxdepth 1 -mindepth 1 -print0 | xargs -0대신 할 수 있습니다ls | xargs
flob

답변:


35

STDIN과 인수라는 두 가지 매우 다른 입력 유형을 혼동하고 있습니다. 인수는 일반적으로 명령 이름 뒤에 (예 : echo these are some arguments또는 rm file1 file2) 지정하여 시작될 때 명령에 제공되는 문자열 목록입니다 . 반면에 STDIN은 명령이 시작된 후 (선택적으로) 읽을 수있는 바이트 스트림 (때로는 텍스트가 아닌 경우도 있음)입니다. 다음은 몇 가지 예입니다 ( cat인수 또는 STDIN 을 사용할 수 있지만 각기 다른 작업을 수행함).

echo file1 file2 | cat    # Prints "file1 file2", since that's the stream of
                          # bytes that echo passed to cat's STDIN
cat file1 file2    # Prints the CONTENTS of file1 and file2
echo file1 file2 | rm    # Prints an error message, since rm expects arguments
                         # and doesn't read from STDIN

xargs STDIN 스타일 입력을 인수로 변환하는 것으로 생각할 수 있습니다.

echo file1 file2 | cat    # Prints "file1 file2"
echo file1 file2 | xargs cat    # Prints the CONTENTS of file1 and file2

echo 실제로 반대의 경우가 많습니다 : 인수를 STDOUT (다른 명령의 STDIN으로 파이프 할 수 있음)으로 변환합니다.

echo file1 file2 | echo    # Prints a blank line, since echo doesn't read from STDIN
echo file1 file2 | xargs echo    # Prints "file1 file2" -- the first echo turns
                                 # them from arguments into STDOUT, xargs turns
                                 # them back into arguments, and the second echo
                                 # turns them back into STDOUT
echo file1 file2 | xargs echo | xargs echo | xargs echo | xargs echo    # Similar,
                                 # except that it converts back and forth between
                                 # args and STDOUT several times before finally
                                 # printing "file1 file2" to STDOUT.

9

cat입력을 STDIN받고 rm받지 않습니다. 이러한 명령의 경우 한 줄씩 xargs반복 STDIN하고 명령 줄 매개 변수를 사용하여 명령을 실행해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.