23
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

bashの組み込みコマンド local について

Last updated at Posted at 2018-02-05

はじめに

本項ではbashの組み込みコマンドである local を扱います。
変数のスコープを関数内に限定するために使用しています。

執筆のきっかけ

執筆のきっかけは以下のようなシェルスクリプトを組んでいる際にはまったことです。

hoge.sh
function foo() {
        local hoge="$(curl http://localhost/testpage)"
        test "${?}" -ne 0 && return 1
        echo hoge
}

foo

exit ${?}

処理の流れは以下のようなものになります。

  1. 関数内であるコマンドの処理結果を変数に格納
  2. あるコマンドが失敗した場合、リターンコードに異常終了を表す数値(例では1)を返却し関数を抜ける
  3. 成功した場合のみ、後続処理を行う。

※実際にやりたかったコマンドはcurlではなくミドルウェア製品独自のコマンドです。失敗する可能性があり、"${?}"に0以外が格納されるコマンドをイメージしてください。

はまったこと

先述の hoge.shcurl http://localhost/testpage が失敗しても "${?}"常に 0が格納されます。
よって、return 1 が機能することはありませんでした。

はまった原因

$? は直前のコマンドの終了値を格納する」という定義の通り、bashの localコマンドの終了値を格納し続けていたため、$? が常に0になっていました。

対処方法

man local を参照すると「local [option] [name[=value] ...]」との記載があるので、変数名のみで宣言が可能そうと気づきました。
以下のようなスクリプトを作成、実行したところ、想定通りに動作しました。

local_test.sh
#!/bin/bash
## FUNCTIONS ##
function foo() {
        local hoge
        hoge="$(bash -c "exit 1")"
        local rc="${?}"
        echo "local.hoge: ${hoge}"
        echo "local.hoge.rc: ${rc}"
}

## MAIN ##
hoge="fugafuga"

foo

echo "global.hoge: ${hoge}"
$ ./test.sh
local.hoge:
local.hoge.rc: 1
global.hoge: fugafuga

おわりに

些細なことですがバグの原因になるところでした。
local を利用して変数の宣言と同時にコマンドの出力を変数に代入しエラーハンドリングを行う場合は、「変数宣言」、「値の代入」を別々に行うことでコマンドのリターンコードを"${?}"で拾えるようになります。

23
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?