サーチ…
構文
function
キーワードを使用して関数を定義する:function f {
}
関数を
()
定義する:f(){
}
function
キーワードと()
両方を持つ関数を定義します。function f(){
}
シンプルファンクション
helloWorld.sh
#!/bin/bash
# Define a function greet
greet ()
{
echo "Hello World!"
}
# Call the function greet
greet
スクリプトを実行すると、メッセージが表示されます
$ bash helloWorld.sh
Hello World!
関数を使ってファイルをソーシングすると、現在のbashセッションでファイルを利用できることに注意してください。
$ source helloWorld.sh # or, more portably, ". helloWorld.sh"
$ greet
Hello World!
いくつかのシェルで関数をexport
、子プロセスに公開することができます。
bash -c 'greet' # fails
export -f greet # export function; note -f
bash -c 'greet' # success
引数を持つ関数
helloJohn.sh
:
#!/bin/bash
greet() {
local name="$1"
echo "Hello, $name"
}
greet "John Doe"
# running above script
$ bash helloJohn.sh
Hello, John Doe
どのような方法でも引数を変更しない場合は、それを
local
変数にコピーする必要はありません。単にecho "Hello, $1"
ます。$1
、$2
、$3
などを使用して、関数内の引数にアクセスすることができます。注意:引数が9
$10
以上の場合は動作しません(bashは$ 1 0として読み込みます)。${10}
、${11}
などを実行する必要があります。$@
は関数のすべての引数を参照します:#!/bin/bash foo() { echo "$@" } foo 1 2 3 # output => 1 2 3
注意:ここのように、実際には必ず
"$@"
前後に二重引用符を使用してください。引用符を省略すると、シェルはワイルドカードを展開します(ユーザがそれを避けるために特に引用した場合でも)。そして、一般的に望ましくない動作や潜在的なセキュリティ問題を引き起こします。
foo "string with spaces;" '$HOME' "*" # output => string with spaces; $HOME *
デフォルトの引数は
${1:-default_val}
です。例えば:#!/bin/bash foo() { local val=${1:-25} echo "$val" } foo # output => 25 foo 30 # output => 30
引数を必要とする
${var:?error message}
foo() { local val=${1:?Must provide an argument} echo "$val" }
関数からの戻り値
Bashのreturn
文はC-関数のような値を返しませんが、代わりに戻り状態の関数を終了します。その関数の終了ステータスと考えることができます。
関数から値を返す場合は、次のようにstdout
値を送ります:
fun() {
local var="Sample value to be returned"
echo "$var"
#printf "%s\n" "$var"
}
今、もしあなたが:
var="$(fun)"
fun
の出力は$var
格納されます。
フラグとオプションのパラメータの処理
getopts組み込み関数は、関数内で使用して、フラグとオプションのパラメーターを収容する関数を記述することができます。これは特別な困難はありませんが、 getoptsが扱う値を適切に処理する必要があります。例として、 stderrにメッセージを書き込み、コード1またはパラメータとして-x
オプションに指定された任意のコードで終了するfailwith関数を定義します。
# failwith [-x STATUS] PRINTF-LIKE-ARGV
# Fail with the given diagnostic message
#
# The -x flag can be used to convey a custom exit status, instead of
# the value 1. A newline is automatically added to the output.
failwith()
{
local OPTIND OPTION OPTARG status
status=1
OPTIND=1
while getopts 'x:' OPTION; do
case ${OPTION} in
x) status="${OPTARG}";;
*) 1>&2 printf 'failwith: %s: Unsupported option.\n' "${OPTION}";;
esac
done
shift $(( OPTIND - 1 ))
{
printf 'Failure: '
printf "$@"
printf '\n'
} 1>&2
exit "${status}"
}
この関数は次のように使用できます。
failwith '%s: File not found.' "${filename}"
failwith -x 70 'General internal error.'
等々。
printfについては 、変数を第1引数として使用しないでください。印刷するメッセージが変数の内容で構成されている場合は、 %s
指定子を使用して
failwith '%s' "${message}"
関数の終了コードは、最後のコマンドの終了コードです
ホストが稼働しているかどうかをチェックするこの関数例を考えてみましょう:
is_alive() {
ping -c1 "$1" &> /dev/null
}
この関数は、最初の関数パラメータで指定されたホストに単一のpingを送信します。 ping
の出力とエラー出力はどちらも/dev/null
リダイレクトされるため、関数は何も出力しません。しかし、 ping
コマンドは成功した場合には終了コード0を、失敗した場合にはゼロ以外の値を返します。これが関数の最後の(そしてこの例では唯一の)コマンドなので、 ping
の終了コードは関数自体の終了コードに再利用されます。
この事実は条件文で非常に有用です。
たとえば、ホストgraucho
が起動している場合は、 ssh
接続しssh
。
if is_alive graucho; then
ssh graucho
fi
別の例:ホストgraucho
が起動するまで繰り返しチェックし、 ssh
接続しssh
。
while ! is_alive graucho; do
sleep 5
done
ssh graucho
関数定義を出力する
getfunc() {
declare -f "$@"
}
function func(){
echo "I am a sample function"
}
funcd="$(getfunc func)"
getfunc func # or echo "$funcd"
出力:
func ()
{
echo "I am a sample function"
}
名前付きパラメータを受け取る関数
foo() {
while [[ "$#" -gt 0 ]]
do
case $1 in
-f|--follow)
local FOLLOW="following"
;;
-t|--tail)
local TAIL="tail=$2"
;;
esac
shift
done
echo "FOLLOW: $FOLLOW"
echo "TAIL: $TAIL"
}
使用例:
foo -f
foo -t 10
foo -f --tail 10
foo --follow --tail 10