1
1

More than 5 years have passed since last update.

[バグか仕様か?] FreeBSD /bin/shにおける-mオプションの挙動

Posted at

FreeBSDの/bin/shで、他実装とは違うヘンな挙動を見つけたのでメモ書き。

まずは、このテストコード(setm_test.sh)を書いてください。

setm_test.sh
#! /bin/sh

set -m                # ←コレをつけると不可解な動きをする

# 終了時のトラップ設定
exit_trap() {
  trap INT
  echo "EXIT_TRAPPED"
  exit 1;
}
trap 'exit_trap' INT

# メインルーチン(sleepを実行して終了を通知する)
sleep 5 || echo $?
echo "FINISH_SLEEPING"
trap INT

冒頭に出てくる-mというオプションは、ジョブ制御を有効にするためのものです。具体的には、

  • ジョブ完了メッセージ(“[1] Done”のようなメッセ^時)が出る。(非対話のシェルスクリプトのデフォルトでは表示されない)
  • fgコマンドのような、ジョブ制御コマンドが使えるようになる。(非対話のシェルスクリプトのデフォルトでは、エラーメッセージが出て使えない)

などの効果があります。

書いたら実行してみください。

(1)起動するだけで何もせず、終了を待つ。

$ sh setm_test.sh
FINISH_SLEEPING
$ 

5秒経過したらFINISH_SLEEPINGと表示されて終了します。

(2)起動したら5秒以内に[CTRL]+[C]を押して止める

CentOS6,Ubuntu14,AIX7.1で試した場合
$ sh setm_test.sh
^CEXIT_TRAPPED
$ 
FreeBSD10で試した場合
$ ./setm_test.sh
^C130
FINISH_SLEEPING
$ 

なんとOSによって挙動が変わります。FreeBSD以外だと、シェルが[CTRL]+[C]によるSIGINTを受け取ると、現在実行中のsleepコマンドを中断させ、trap設定してあったexit_trap関数へ制御を移します。

ところが、FreeBSDだと、sleepコマンドを中断させた後、そのままメインルーチンを続行してしまうのです。これっておかしくないでしょうか?

シェルではなくOSの問題?それとも仕様?

この問題、bashでも起こります。

FreeBSD10で試した場合
$ bash setm_test.sh
^C130
FINISH_SLEEPING
$ 

shだけで起こるならshのバグと思えそうですが、シェルを替えても起こるのでOSのバグなのか、それともFreeBSDの仕様なのか。

どちらなのか、現状では判断がつきません。(Macとかどうかなのかな?)

心当たりの方、是非コメントください。

1
1
6

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
1
1