programing

stdin 입력이 비어 있는 경우 xargs 명령을 무시하는 방법은 무엇입니까?

newsource 2023. 5. 20. 10:51

stdin 입력이 비어 있는 경우 xargs 명령을 무시하는 방법은 무엇입니까?

다음 명령을 고려합니다.

ls /mydir/*.txt | xargs chown root

에 있는 모든 텍스트 입니다.mydir뿌리째 뽑힌

에 문는만없이 없다면 입니다..txt에 있는 :mydir그런 다음 xargs는 경로가 지정되지 않았다는 오류를 표시합니다.이것은 오류가 발생하고 있기 때문에 해롭지 않은 예이지만, 여기서 사용해야 하는 스크립트와 같은 경우에는 빈 경로가 현재 디렉터리로 가정됩니다.그래서 만약 내가 그 명령을 실행한다면,/home/tom/▁for,▁result면없에 대한 결과가 없다면,ls /mydir/*.txt 아의모파일에 있는 /home/tom/소유자를 루트로 변경합니다.

그럼 어떻게 하면 xargs가 빈 결과를 무시하도록 할 수 있습니까?

GNU의 »xargs은 수있다니습사를 할 수 .-r또는--no-run-if-empty옵션:

--no-run-if-empty
-r
표준 입력에 공백이 없는 경우 명령을 실행하지 마십시오.일반적으로 명령은 입력이 없더라도 한 번 실행됩니다.이 옵션은 GNU 확장입니다.

xargs은 빈 대한 하지 않기 때문에 macOS에서 사용되는 명령어입니다.-r하지 않습니다. (.)xargs).

GNU 가 아닌 는 GNU xarg를 할 수 .-L <#lines>,-n <#args>,-i,그리고.-I <string>:

ls /empty_dir/ | xargs -n10 chown root # chown executed every 10 args or fewer
ls /empty_dir/ | xargs -L10 chown root # chown executed every 10 lines or fewer
ls /empty_dir/ | xargs -i cp {} {}.bak # every {} is replaced with the args from one input line
ls /empty_dir/ | xargs -I ARG cp ARG ARG.bak # like -i, with a user-specified placeholder

xargs는 공백에서 선을 분할하지만 견적 및 이스케이프를 사용할 수 있습니다. 자세한 내용은 RTFM을 참조하십시오.

또한 Doron Behar가 언급했듯이 이 해결 방법은 휴대용이 아니므로 확인이 필요할 수 있습니다.

$ uname -is
SunOS sun4v
$ xargs -n1 echo blah < /dev/null
$ uname -is
Linux x86_64
$ xargs --version | head -1
xargs (GNU findutils) 4.7.0-git
$ xargs -n1 echo blah < /dev/null
blah

man xargs말한다--no-run-if-empty.

▁▁in면에.xargs사용할 수 있습니다.-r제안된 제된대, 그나에 BSD 지되않습에서 .xargs.

해결 방법으로 다음과 같은 추가 임시 파일을 전달할 수 있습니다.

find /mydir -type f -name "*.txt" -print0 | xargs -0 chown root $(mktemp)

null로 ("stderr" null").2> /dev/null 예:

find /mydir -type f -name "*.txt" -print0 | xargs -0 chown root 2> /dev/null || true

다른 더 나은 접근 방식은 다음을 사용하여 발견된 파일을 반복하는 것입니다.while슬롯:슬라이드:

find /mydir -type f -name "*.txt" -print0 | while IFS= read -r -d '' file; do
  chown -v root "$file"
done

참고 항목:Mac OS X의 xarg에 대한 빈 결과 무시


또한 권한을 변경하는 방법이 좋지 않고 권장되지 않는다는 점도 않습니다.명령의 출력을 구문 분석하면 안 됩니다(ls의 출력을 구문 분석하면 되는 이유 참조).특히 루트별로 명령을 실행할 때 파일이 셸에서 해석할 수 있는 특수 문자로 구성되거나 파일에 공백 문자가 있는 것을 상상할 수 있기 때문입니다./결과가 끔찍할 수 있습니다.

라서접방변사합용니야다해고하경식을따근합다니▁change를 사용해야 합니다.find대신 명령(예:

find /mydir -type f -name "*.txt" -execdir chown root {} ';'

사용할 수 있는 대체 플랫폼(Mac 및 Linux)-r/--no-run-if-emptyxargs의 매개 변수:

빈 매개 변수의 예(Ubuntu 18.04 및 BigSur의 경우 동일한 결과):

$ echo | xargs -I {}  echo "This is a test with '{}'"
$
$
$ cat /dev/null | xargs -I {}  echo "This is a test with '{}'"
$

선이 여러 개인 예:

$ seq 1 5  | xargs -I {}  echo "This is a test with '{}'"
This is a test with '1'
This is a test with '2'
This is a test with '3'
This is a test with '4'
This is a test with '5'
$

이것은 -r, --no-run-if-empty를 사용하여 억제할 수 있는 GNU xargs의 동작입니다.

*BSD 변형 xargs에는 기본적으로 이 동작이 있으므로 -r이 필요하지 않습니다.FreeBSD 7.1(2009년 1월 출시) 이후 호환성을 위해 -r 인수가 허용됩니다(스위치는 아무것도 하지 않습니다).

저는 개인적으로 스크립트에서 longopt를 사용하는 것을 선호하지만 *BSD xargs는 longopt를 사용하지 않기 때문에 "-r"만 사용하고 xargs는 *BSD에서 Linux 시스템에서 동일하게 작동합니다.

MacOS(현재 MacOS Mojave)의 xargs는 슬프게도 "-r" 인수를 지원하지 않습니다.

OSX에서: Bash 재구현xargs을 다루는-r논쟁, 예를 들어.$HOME/bin에 추가합니다.PATH:

#!/bin/bash
stdin=$(cat <&0)
if [[ $1 == "-r" ]] || [[ $1 == "--no-run-if-empty" ]]
then
    # shift the arguments to get rid of the "-r" that is not valid on OSX
    shift
    # wc -l return some whitespaces, let's get rid of them with tr
    linecount=$(echo $stdin | grep -v "^$" | wc -l | tr -d '[:space:]') 
    if [ "x$linecount" = "x0" ]
    then
      exit 0
    fi
fi

# grep returns an error code for no matching lines, so only activate error checks from here
set -e
set -o pipefail
echo $stdin | /usr/bin/xargs $@

언급URL : https://stackoverflow.com/questions/8296710/how-to-ignore-xargs-commands-if-stdin-input-is-empty