関数がどのように値を返すかをテストするために書いたシェル スクリプトで、奇妙な予期しない動作に遭遇しました。以下のコードは、関数 fnttmpfile に入ると、最初の echo ステートメントがコンソールに出力され、次に 2 番目の echo ステートメントが呼び出し元のメインに実際に文字列を返すことを前提としています。と思ったのですが、それは間違いでした!
#!/bin/sh
fntmpfile() {
TMPFILE=/tmp/$1.$$
echo "This is my temp file dude!"
echo "$TMPFILE"
}
mainname=main
retval=$(fntmpfile "$mainname")
echo "main retval=$retval"
実際に起こることは逆です。最初のエコーは呼び出し元の関数に送られ、2 番目のエコーは STDOUT に送られます。これはなぜですか?もっと良い方法はありますか....
main retval=これは私の一時ファイルです! /tmp/main.19121
このテストの全体的な理由は、いくつかのデータベース バックアップを実行するシェル スクリプトを作成していて、特定のことを実行するために小さな関数を使用することにしたためです。私が使用していた機能の1つはこれでした:
log_to_console() {
# arg1 = calling function name
# arg2 = message to log
printf "$1 - $2\n"
}
これに関する全体的な問題は、文字列値を返していた関数が、順序に応じて代わりに log_to_console 出力を取得していることです。これは、私が気付いていなかったシェル スクリプトに関する落とし穴の 1 つだと思います。