기반으로이 답변, 파일 설명자 1과 2를 교환하기 위해 다음을 작성했습니다.
swap12
:
#!/bin/bash
"$@" 3>&1 1>&2 2>&3 3>&-
그런 다음 파이프라인에서 STDERR을 작업할 수 있습니다. 예를 들면 다음과 같습니다.
$ swap12 ls -ld /tmp /ooooooo | tr o X
ls: cannXt access '/XXXXXXX': NX such file Xr directXry
drwxrwxrwt 19 root root 1400 Jul 1 17:14 /tmp
그러나 FD를 여러 번 교체하면 작동하지 않습니다.
$ swap12 ls -ld /tmp /ooooooo | swap12 tr o X | tr o Z
ls: cannXt access '/XXXXXXX': NX such file Xr directXry
drwxrwxrwt 19 root root 1400 Jul 1 17:14 /tmp
위에서는 두 번째가 swap12
STDOUT과 STDRR을 다시 교환할 것으로 예상하므로 두 번째는 원래 STDOUT에서 작동합니다 tr
. ls
나는 다음을 보기를 고대하고 있다:
$ swap12 ls -ld /tmp /ooooooo | swap12 tr o X | tr o Z
ls: cannXt access '/XXXXXXX': NX such file Xr directXry
drwxrwxrwt 19 rZZt rZZt 1400 Jul 1 17:14 /tmp
내가 원하는 것을 어떻게 달성할 수 있나요?
내 문제는 서브셸에서 파일 설명자를 변경하여 발생한 것 같습니다. 전역 별칭 으로 zsh
구현하면 이점이 있습니까 alias -g
? (그러나 bash
실제로는 어떤 모습일까요?)
답변1
일반적으로 stderr
터미널로 직접 이동하여 stdout
파이프를 입력하십시오.
ls stdout -->
ls -ld /tmp /ooooooo | tr o X
|
v ls stderr (to terminal)
교체한 후 stdout
파이프가 아닌 터미널로 이동합니다.
ls stderr -->
swap12 ls -ld /tmp /ooooooo | tr o X
|
v ls stdout
/ 교환은 이전에 파이프에서 리디렉션되었으므로 stdout
어떤 방식으로든 결과를 포함하지 않습니다 .stderr
tr
stderr
ls
ls stderr --> tr stderr -->
swap12 ls -ld /tmp /ooooooo | swap12 tr o X | tr o Z
| |
v ls stdout v tr stdout
stdout
및 stderr
를 별도로 처리하려면 ls
프로세스 대체를 사용할 수 있습니다(Bash 및 Zsh에서 작동해야 함).
$ ls -ld /tmp /ooooooo 2> >(tr o X) > >(tr o Z)
ls: cannXt access '/XXXXXXX': NX such file Xr directXry
drwxrwxrwt 25 rZZt rZZt 4096 Jul 1 14:40 /tmp/
답변2
파이프는 ls.stderr
에 연결됩니다 tr1.stdin
. 그런 다음 tr2 로 교환 tr1.stdout
하고 tr1.stderr
파이프하여 s 가 없음을 확인하므로 아무것도 하지 마십시오.tr1.stderr
tr2.stdin
o
두 번째는 swap12
첫 번째를 취소해서는 안 되며 앞으로도 취소하지 않을 것입니다.
이걸 할 건가요 ./swap12 ./swap12 ls -ld /tmp /ooooooo | tr o X
? 이렇게 하면 스왑이 취소됩니다.