95
49

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.

Tips: 実行中のシェルスクリプトを書きかえるときには

Last updated at Posted at 2018-07-14

実行中のシェルスクリプトを編集すると実行している途中から動作を変えることができることはよく知られている。 例: http://d.hatena.ne.jp/sleepy_yoshi/20090917/p1

「変えることができる」というよりも現実のケースでは、実行中に意図せず内容を変えてしまうことで予想しない挙動をさせてしまうことがありうる。これを防ぐにはどうするか。

次のようなスクリプトを実行中に書き換えてみる

run.sh
#!/bin/sh
sleep 30
echo foo
$ run.sh &
$ vim run.sh
(30 秒以内に foo を bar に変えて保存する)
bar

編集後の bar という文字が表示されてしまう。
この例ではまだマシだが、現実のケースでは予期せずして if 文まるごと貫通するなど、破滅をもたらしてしまうことがある。

対策

新たにファイルを作成しなおして編集すればいい。
シェルが掴んでいるのは旧い i-node のファイルの方で、新たに編集する方とは別の i-node にする。

特に cp して mv すると楽。

$ run.sh &
$ cp run.sh run.sh.tmp
$ mv run.sh.tmp run.sh
$ vim run.sh
(30 秒以内に foo を bar に変えて保存する)
foo

ちゃんと結果は foo のままになっている。

超余談

リネームは bash の展開を使うと間違えにくく、楽

$ cp run.sh{,.tmp}
$ mv run.sh{.tmp,}

テスト

最近は私はなるべく Tips もテストつきで管理しています。そうすると Tips が時代の変化に強くなります。

95
49
2

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
95
49

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?