문제

hi.txt 및 blah.txt가있는 디렉토리가 있고 Linux-ish 명령 줄에서 다음 명령을 실행한다고 가정 해보십시오.

ls *.* | xargs -t -i{} echo {}

당신이 볼 수있는 출력은입니다

echo blah.txt
blah.txt
echo hi.txt
hi.txt

Stderr 출력을 리디렉션하고 싶습니다 ( 'echo blah.txt'실패 ...), XARGS -T 명령에서 출력 만 남겨 둡니다 STD에 쓰여졌지만 STDERR 인 것처럼 보입니다.

ls *.* | xargs -t -i{} echo {} 2> /dev/null

Stdout에 출력 할 수있는 방법이 있습니까?

도움이 되었습니까?

해결책

그래서 나는 당신이 원하는 것이 stdout처럼

  • XARGS가 실행하는 유틸리티에서 나온 stdout
  • XARGS -T가 생성 한 명령 목록

실행 된 유틸리티에 의해 생성 된 Stderr 스트림을 무시하고 싶습니다.

내가 틀렸다면 제발 수정 해주세요.

먼저 더 나은 테스트 유틸리티를 만들어 봅시다.

% cat myecho
#!/bin/sh
echo STDOUT $@
echo STDERR $@ 1>&2
% chmod +x myecho
% ./myecho hello world
STDOUT hello world
STDERR hello world
% ./myecho hello world >/dev/null
STDERR hello world
% ./myecho hello world 2>/dev/null
STDOUT hello world
%

이제 우리는 실제로 stdout과 stderr에 실제로 출력하는 것이 있으므로 우리가 원하는 것을 얻는 것만 확신 할 수 있습니다.

이를 수행하는 접선 방법은 Xargs를 사용하는 것이 아니라 오히려 만드는 것입니다. 명령을 반향 한 다음 그것을하는 것은 일종의 일입니다. 그게 가방입니다.

% cat Makefile
all: $(shell ls *.*)

$(shell ls): .FORCE
  ./myecho $@ 2>/dev/null

.FORCE:
% make
./myecho blah.txt 2>/dev/null
STDOUT blah.txt
./myecho hi.txt 2>/dev/null
STDOUT hi.txt
% make >/dev/null
% 

Xargs를 사용하는 데 묶인 경우 Xargs가 사용하는 유틸리티를 수정하여 stderr를 압박해야합니다. 그런 다음 사용할 수 있습니다 2>&1 트릭은 다른 사람들이 Xargs -t에 의해 생성 된 명령 목록을 STDERR에서 STDOUT로 옮기라고 언급했습니다.

% cat myecho2
#!/bin/sh
./myecho $@ 2>/dev/null
% chmod +x myecho2
% ./myecho2 hello world
STDOUT hello world
% ls *.* | xargs -t -i{} ./myecho2 {} 2>&1
./myecho blah.txt 2>/dev/null
STDOUT blah.txt
./myecho hi.txt 2>/dev/null
STDOUT hi.txt
% ls *.* | xargs -t -i{} ./myecho2 {} 2>&1 | tee >/dev/null
%

따라서이 접근 방식은 작동하고 원하는 모든 것을 붕괴시킵니다 (원하지 않는 것을 남기십시오).

자신 이이 일을 많이한다면 Stderr를 압박하기 위해 일반적인 유틸리티를 작성할 수 있습니다.

% cat surpress_stderr
#!/bin/sh
$@ 2>/dev/null
% ./surpress_stderr ./myecho hello world
STDOUT hello world
% ls *.* | xargs -t -i{} ./surpress_stderr ./myecho {} 2>&1
./surpress_stderr ./myecho blah.txt 2>/dev/null
STDOUT blah.txt
./surpress_stderr ./myecho hi.txt 2>/dev/null
STDOUT hi.txt
%

다른 팁

사용:

ls | xargs -t -i{} echo {} 2>&1 >/dev/null

그만큼 2>&1 표준 오류를 보냅니다 xargs 현재 표준 출력이 진행되는 곳으로; 그만큼 >/dev/null 원래 표준 출력을 보냅니다 /dev/null. 따라서 순 결과는 표준 출력에 Echo 명령이 포함되어 있으며 /dev/null 파일 이름을 포함합니다. 우리는 파일 이름의 공간에 대해 토론 할 수 있으며 사용하기가 더 쉬운 지 여부 sed 각 줄의 앞쪽에 'echo'를 넣는 스크립트 ( -t 옵션) 또는 사용할 수 있는지 여부 :

ls | xargs -i{} echo echo {}

(테스트 : Solaris 10, Korn Shell; 다른 쉘 및 유닉스 플랫폼에서 작동해야합니다.)


명령의 내부 작업을보고 싶지 않다면 오류 출력을 분리했습니다. xargs 그리고 명령의 오류 출력이 실행되었습니다.

al * zzz | xargs -t 2>/tmp/xargs.stderr -i{} ksh -c "ls -dl {} 2>&1"

(비표준) 명령 al 인수는 한 줄에 하나를 나열합니다.

for arg in "$@"; do echo "$arg"; done

첫 번째 리디렉션 (2>/tmp/xargs.stderr)에서 오류 출력을 보냅니다 xargs 파일에 /tmp/xargs.stderr. 실행 된 명령은 'ksh -c "ls -dl {} 2>&1"', Korn Shell을 사용하여 실행합니다 ls -ld 오류 출력이 표준 출력으로 이동하는 파일 이름에서.

출력 /tmp/xargs.stderr 보이는 것 같습니다 :

ksh -c ls -dl x1 2>&1
ksh -c ls -dl x2 2>&1
ksh -c ls -dl xxx 2>&1
ksh -c ls -dl zzz 2>&1

나는 사용했다 'ls -ld' 대신에 echo 오류를 테스트하고 있는지 확인하기 위해 파일입니다 x1, x2, 그리고 xxx 존재했지만 zzz 하지 않습니다.

표준 출력의 출력은 다음과 같습니다.

-rw-r--r--   1 jleffler rd          1020 May  9 13:05 x1
-rw-r--r--   1 jleffler rd          1069 May  9 13:07 x2
-rw-r--r--   1 jleffler rd            87 May  9 20:42 xxx
zzz: No such file or directory

명령없이 실행할 때 'ksh -c "..."', I/O 리디렉션은 명령에 대한 인수로 전달되었습니다 ('ls -ld') 따라서 파일을 찾을 수 없다고보고했습니다.2>&1'. 그건, xargs 자체가 쉘을 사용하여 I/O 리디렉션을 수행하지 않았습니다.

다른 다양한 리디렉션을 준비하는 것이 가능하지만 기본적인 문제는 xargs 자체 오류 출력을 실행하는 명령의 오류 출력과 분리 할 수있는 조항을 제공하지 않으므로 수행하기가 어렵습니다.

다른 명백한 옵션은 사용하는 것입니다 xargs 쉘 스크립트를 작성한 다음 쉘이 실행하도록합니다. 이것은 내가 전에 보여준 옵션입니다.

ls | xargs -i{} echo echo {} >/tmp/new.script

그런 다음 다음과 같이 명령을 볼 수 있습니다.

cat /tmp/new.script

명령을 실행하여 오류를 버릴 수 있습니다.

sh /tmp/new.script 2>/dev/null

그리고 명령에서 표준 출력을보고 싶지 않다면 Append 1>&2 명령의 끝까지.

xargs -t 명령을 실행하기 전에 stderr로 실행해야합니다. 대신 stderr로 에코를 원한다면 stderr가 2>&1 건설하다:

ls *.* | xargs -t -i{} echo {} 2>&1

Xargs -t가 Stderr로 이동하는 것처럼 보이며, 그것에 대해 할 수있는 일은 많지 않습니다.

당신은 할 수 있습니다 :

ls | xargs -t -i{} echo "Foo: {}" >stderr.txt | tee stderr.txt

명령이 실행될 때 터미널의 STDERR 데이터 만 표시 한 다음 STDERR.TXT를 통해 예상치 못한 일이 발생했는지 확인한 후에는 줄을 따라 줄입니다. grep -v Foo: stderr.txt

또한 유닉스에서 ls *.* 모든 것을 표시하는 방법은 아닙니다. 모든 파일을보고 싶다면 그냥 실행하십시오. ls 그 자체로.

GNU 병렬을 사용하여 문제를 이해합니다 http://www.gnu.org/software/parallel/ 옳은 일을 할 것입니다 :

ls *.* | parallel -v echo {} 2> /dev/null
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top