混乱したエラーが発生しましたが、よりよく理解したいと思います。この問題は「ラッパー」シェル関数(以下の説明)の存在を必要とするようです。 (投稿の末尾に私の問題についてより具体的に説明しました。)
このエラーを再現するために私が思いついた最も簡単なコードは、次のスクリプトにあります。 (スクリプトは確かに人為的で愚かですが、最初のエラーが発生する現実はこのようなデモに比べて複雑すぎます。)
# create an input file
cat <<EOF > demo.txt
a
b
c
EOF
# create a "wrapper shell function" for /usr/bin/join
my_join_fn () {
/usr/bin/join "$@"
}
cat <(my_join_fn <(cat demo.txt) <(cat demo.txt))
cat <(my_join_fn <(cat demo.txt) <(cat demo.txt)) | head -1
# create a "wrapper shell function" for /usr/local/bin/gjoin, a port of
# GNU's join function for OS X
my_gjoin_fn () {
/usr/local/bin/gjoin "$@"
}
cat <(my_gjoin_fn <(cat demo.txt) <(cat demo.txt))
cat <(my_gjoin_fn <(cat demo.txt) <(cat demo.txt)) | head -1
# show the version of zsh
$SHELL --version
誰かがこのスクリプトをソースとして使用すると(zsh
)正常に終了し、次の(正しい)出力が生成されます。
% source demo.sh
a
b
c
a
a
b
c
a
zsh 5.0.2 (x86_64-apple-darwin11.4.2)
しかし、後でもう一度実行するとコマンドラインから直接、で終わるスクリプトの2行のうちの1つでエラーが| head -1
発生しますbad file descriptor
。
% cat <(my_join_fn <(cat demo.txt) <(cat demo.txt)) | head -1
join: /dev/fd/11: Bad file descriptor
% cat <(my_gjoin_fn <(cat demo.txt) <(cat demo.txt)) | head -1
/usr/local/bin/gjoin: /dev/fd/11: Bad file descriptor
これは、コマンドラインから直接実行するときにエラーが発生するスクリプトの唯一の2行です。
出力結果からわかるように、$SHELL --version
上記の結果はOS Xで得られたものですが、Linuxでも同様のテストを実行したときに同様の結果が得られました。
% cat <(my_join_fn <(cat demo.txt) <(cat demo.txt)) | head -1
/usr/bin/join: /proc/self/fd/11: No such file or directory
% $SHELL --version
zsh 4.3.10 (x86_64-unknown-linux-gnu)
bash
(OS XまたはLinux)ではこのエラーを再現できません。zsh
これにより、このバグが 。
だから解決策を探したいです。私の質問は次のとおりです
my_gjoin_fn
このエラーを回避するには、ラッピングシェル関数の定義をどのように修正する必要がありますか?
(実際の対応は、my_gjoin_fn
フラグが呼び出しに含まれることを除いて、上記のものとほぼ同じですgjoin
。
my_gjoin_fn () {
/usr/local/bin/gjoin -t$'\t' "$@"
}
これを使用してシェル関数をラップします。いつもだから私はそれを「保存」したいと思いました。 )
編集する:
| head -1
| head -10
コマンドの終わりを、、、| cat
などに置き換えても| tee /dev/null
エラーがまだ存在します。| :
たとえば、
% cat <(my_join_fn <(cat demo.txt) <(cat demo.txt)) | cat
/usr/bin/join: /proc/self/fd/11: No such file or directory
また、ls -l /proc/self/fd
mswが提案したように追加すると、次の結果が得られます。
% cat <(ls -l /proc/self/fd; my_join_fn <(cat demo.txt) <(cat demo.txt)) | cat
total 0
lrwx------ 1 jones jones 64 Aug 21 12:29 0 -> /dev/pts/18
l-wx------ 1 jones jones 64 Aug 21 12:29 1 -> pipe:[312539706]
lrwx------ 1 jones jones 64 Aug 21 12:29 2 -> /dev/pts/18
lr-x------ 1 jones jones 64 Aug 21 12:29 3 -> /proc/23849/fd
/usr/bin/join: /proc/self/fd/11: No such file or directory
...それは意味がありません。私他にも多くの情報を提供できます。 FWIW、ls -l /proc/self/fd
私が入るかzsh
出るかbash
、またFWIW、ls -l /proc/self/fd
単独で実行したときの出力は次のとおりです。
% ls -l /proc/self/fd
total 0
lrwx------ 1 jones jones 64 Aug 21 12:32 0 -> /dev/pts/18
lrwx------ 1 jones jones 64 Aug 21 12:32 1 -> /dev/pts/18
lrwx------ 1 jones jones 64 Aug 21 12:32 2 -> /dev/pts/18
lr-x------ 1 jones jones 64 Aug 21 12:32 3 -> /proc/5246/fd
答え1
で動作を再現できましたzsh 4.3.10 (i686-pc-linux-gnu)
。
% cat <(funjoin <(cat demo) <(cat demo)) | head -1
join: /proc/self/fd/11: No such file or directory
私はマニュアルを掘り下げ、この問題に最も近いのがProcess Substitution in man zshexpn
and MULTIOS in Chaptersであることを発見しましたman zshmisc
。
両方の章は、コマンド部分に中かっこを入れることに関連する解決策を提案します。
頑張った
% { cat <(funjoin <(cat demo) <(cat demo)) } | head -1
1
効果がある
{ }
zshの意味をよく理解できません。マニュアルでは、単に命令のリストとして説明します。私はこのMULTIOSが何をしているのか完全には理解していません。有効または無効にしても、あまり差がないようです。
関数本体の内部を含む他の場所に中かっこを配置しようとしましたが、funjoin
正しく機能する唯一の場所は外部ですcat
。
答え2
Linuxでは、zsh_5.0.0-2ubuntu3_amd64.debの下でこれを再現できませんでしたが、/proc/self/fd/11
かなり高い数字のようです。ただ失敗しますかhead -1
?どうですかhead -10
?出力許可
cat <(ls -l /proc/self/fd ; my_join_fn <(cat demo.txt) <(cat demo.txt)) | head -1
照明が出ますか?