`xargs -t` output stderr 또는 stdout입니까?
-
20-08-2019 - |
문제
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