に基づいてこの回答、ファイル記述子 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
上記では、2番目はswap12
STDOUTとSTDRRを交換することを期待しているため、2番目は元の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
2番目はswap12
最初をキャンセルしてはいけません。
これをするつもりですか./swap12 ./swap12 ls -ld /tmp /ooooooo | tr o X
?これによりスワップがキャンセルされます。