mattintosh note

どこかのエンジニアモドキの備忘録

bash のエクスポートされた関数の謎

bash で関数をエクスポートして遊んでいるときに不思議な現象に遭遇した。

md2html()
{
    perl /usr/local/bin/Markdown.pl "$1" | cat /dev/fd/3 - /dev/fd/4 3<<EOS1 4<<EOS2
<!doctype html><html><body>
EOS1
</body></html>
EOS2
}

これをエクスポートして実行すると /dev/fd/4 が開けないというエラーになる。

というわけでなんか色々試してみる。リダイレクトの順番とかは適当で。

foo()
{
    echo 1 | cat - | cat -
    { echo 2; echo 3; echo 4; } | cat -
    echo 6 | { echo 5 | cat - /dev/fd/3; } 3<&0
    echo 9 | { echo 8 | { echo 7 | cat - /dev/fd/4 /dev/fd/3; } 4<&0; } 3<&0
    cat <<EOS1
10
EOS1
    cat /dev/fd/3 3<<EOS1
11
EOS1
    cat - /dev/fd/3 /dev/fd/4 <<EOS1 3<<EOS2 4<<EOS3
12
EOS1
13
EOS2
14
EOS3
}

foo
export -f foo
bash -c foo
1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 cat: /dev/fd/3: Bad file descriptor

-v で見てみる。

foo () {  echo 1 | cat - | cat -;
 {
 echo 2;
 echo 3;
 echo 4
 } | cat -;
 echo 6 | {
 echo 5 | cat - /dev/fd/3
 } 3<&0;
 echo 9 | {
 echo 8 | {
 echo 7 | cat - /dev/fd/4 /dev/fd/3
 } 4<&0
 } 3<&0;
 cat  <<EOS1
10
EOS1

 cat /dev/fd/3  3<<EOS1
11
EOS1

 cat - /dev/fd/3   <<EOS1
12
EOS1
3<<EOS2 # <-- ???
13
EOS2

}

1行にヒアドキュメントを2つ以上書くとだめっぽい。そもそも書き方が邪道か。

GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0) Copyright (C) 2007 Free Software Foundation, Inc.