#初めに
インタラクティブな関数の戻り値を変数に格納する情報が少なかったので、備忘録的に。
#Bashの関数の戻り値について
Bashの関数の戻り値は終了ステータスを返却します。
正常終了だったら「0」を返却するのが一般的です。
#文字列を返却
関数の戻り値に文字列を扱いたい場合は標準出力を利用するのが~~一般的です。~~でもないようです。
※コメントで説明してくださっていますので必読。
#!/bin/bash
function test () {
echo "hello world"
}
result=$(test)
echo "${result}"
実行結果
$ bash ./test.sh
hello world
#インタラクティブな関数の場合
ここからが本題。
キーボードからの入力値を扱う関数の場合は、echoコマンドを利用して入力案内等を出す場合が多いと思います。
#!/bin/bash
function test () {
echo -n "please enter a number: "
read result
}
test
echo "your number is ${result}"
実行結果
$ bash ./test2.sh
please enter a number: 111
your number is 111
##問題点
上記の方法には問題点があります。
キーボードからの入力値を「result」というグローバル変数に格納している部分。
関数「test」の実行結果をechoコマンドで表示していますが、
関数内の変数「result」を関数外でも扱うのは関数化の意味がないとも言えます。
ではキーボードでの入力値を標準出力で返却し、変数に格納する形にしてみます。
#!/bin/bash
function test () {
echo -n "please enter a number: "
read input
echo "${input}"
}
result=$(test)
echo "your number is ${result}"
実行結果
$ bash ./test3.sh
111
your number is please enter a number: 111
Bashを実行しても何も表示されないので、とりあえず数字を入力してみるとこのように表示されました。
関数の結果を変数に格納する場合、全ての標準出力が変数に格納されるので入力案内も変数に格納されてしまいます。
他の言語を経験してからBashを使うようになるともどかしい部分ですね。
##標準エラーを利用する
解決方法は単純で、関数内で表示したい標準出力を全て標準エラーにしてしまえば、
変数には格納されず表示されます。
#!/bin/bash
function test () {
echo -n "please enter a number: " 1>&2
read input
echo "${input}"
}
result=$(test)
echo "your number is ${result}"
実行結果
$ bash ./test4.sh
please enter a number: 111
your number is 111
##別の方法
標準出力全てをエラーにしていくのが煩わしいという方は、関数化してもいいかもしれません。
関数「to_error」は第1引数を標準エラーで出力してくれます。
#!/bin/bash
function to_error () {
echo -n "${1}" 1>&2
}
function test () {
to_error "please enter a number: "
read input
echo "${input}"
}
result=$(test)
echo "your number is ${result}"
実行結果
$ bash ./test5.sh
please enter a number: 111
your number is 111
あまり煩わしさは変わっていませんね。
#まとめ
インタラクティブな関数の戻り値を変数に格納する方法をまとめてみました。
すごく一般的な関数の使い方な気がしますが、調べてみると全然情報がないのが不思議でした。
それとも聞くまでもないようなことなのでしょうか。。。
個人的にはこのやり方は力技過ぎてあまり好きではありませんが、しょうがないみたいです。