シェルスクリプトの set -e は罠いっぱい

set -e が推奨されることがあるが、罠があるので気をつけようぜ。
28
とみたまさひろ🍣🍺 @tmtms

素人なので set -e はよく使う。 twitter.com/satoh_fumiyasu…

2017-04-23 14:26:49
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

俺自身は set -e は使わないが、素人なら使ってもいい (使ったほうがマシ。どうせ他にも残念な点があるだろうから)って立場なんだが、誰かそんな感じの記事書いてくれないかなー。 #シェル芸 twitter.com/qiitapoi/statu…

2017-04-23 13:26:33
まさみさん⋈語りたい @mhiramat

まさにいまset -eの罠にはまった。 set -eをしていると `command` でコマンドの実行結果を得ようとした時 commandがfalseを返すとそのままslientlyに死ぬ。

2017-04-25 18:31:11
Hiroki Sato @Hiroki_Sato

@satoh_fumiyasu f() { false; echo "in f()."; } echo start f && echo "f() returned true." echo end みたいなパターンで "&& echo..." を外した時の挙動が -e 有り無しで変わるのが嫌かなあ。混乱する。

2017-04-26 18:26:09
@ka_

シェルスクリプトには set -ex を最近特に考えず付けるようにしていたのですが自分の場合やはり set -x だけの方が良いと最近思い直しています

2017-04-27 00:27:27
@ka_

シェルスクリプトには set -e つけとけばいいんじゃね??って皆(シェル芸に造形がもともと深かった達人などは除いて)が思い始めたのも同時多発的だったんじゃとか勝手に思ってる

2017-04-27 00:29:17
sat @satoru_takeuchi

set -e、やっつけスクリプトでよく使うな。それを真面目に使うようになってきたら、あるいは元から真面目に書いてるものについてはちゃんとエラー処理するようにして、-eは外す

2017-04-27 08:23:39
NOKUBI Takatsugu野首貴嗣 @knok

debianのpostrmスクリプトに#/bin/sh -e としてあるやつがあって昔はまったな

2017-04-27 08:29:20
hchbaw @hchbaw

これ見ていて。そういえば、例が出てるやつあったよなーと思ってたのがこちら。mywiki.wooledge.org/BashFAQ/105

2017-04-27 09:00:06
hchbaw @hchbaw

一通り目を通して、なんか色々あってうわあ…という感想。“色々ある”って所だけでも把握しておけば足しになります。というかそれ自体を目的とされているという感じですね。助かります。

2017-04-27 09:09:13
tyru @_tyru_

個人的に一番 set -e の罠にハマるのは diff コマンドかなぁ。差分が出ると死ぬ。code=0; diff ... || code=$? してわざわざチェックしたりする / “シェルスクリプトの set -e は罠いっぱ…” htn.to/sGPzWT

2017-04-27 09:27:26
ymmt @ymmt2005

shell のプロは set -e しないのか。 shell 素人の私は shell なるべく避けて Python にひよります 😅

2017-04-27 09:59:23
ふみやす@シェルまおう(自称でない) FGO:838,149,789 @satoh_fumiyasu

$ sh -c 'atexit() { echo $?; }; trap atexit EXIT; set -e; sh -c "exit 123"; echo done' 123 #シェル芸 twitter.com/iri_noi/status…

2017-04-27 09:56:45
羊ヶ丘 めりの🐑⛰ / 入野井 羊🐑 @iri_noi

set -eでエラー出たらそこでシェルスクリプト終わるようにして実際エラー終了してもシグナル0でExitするからtrap文で正常終了時と異常終了時の処理分けられないしどうすればいいんだって感じなんですよね

2016-11-17 21:25:01

2019年末のツイートまとめ

ふみやす@シェルまおう(自称でない) FGO:838,149,789 @satoh_fumiyasu

パイプラインのエラーまで考慮したシェルスクリプトは見たことない。自分も気になってはいて、bash で set -o pipefail して foo |bar |qux || exit $? することもあるが、だいたいはそこまではしてない。 単発のコマンドはもちろん foo || exit $? のようにする。 #シェル芸 twitter.com/mattn_jp/statu…

2019-12-24 21:08:43
mattn @mattn_jp

巷に出回るシェルスクリプトって、よくよく見るとエラー処理ぜんぜんしてないんだよね。そのファイルが無かった場合、その実行モジュールが無かった場合、パイプが途中で切れた場合。それらを全部エラーチェックしたらきっと if err != nil {} みたくなる。

2019-12-24 19:15:27
カウプラン機関極東支部@アルビオン王国民 @_kauplan

@satoh_fumiyasu > set -e では...、シェル関数内では無視される。 本当ですか?次のようなスクリプトを試しましたがbash、dash共に無視されませんでした。 set -e test1 () { ls /notexist echo "listed" # 表示されない } test1 echo "tested" # 表示されない

2019-12-25 11:41:49
ふみやす@シェルまおう(自称でない) FGO:838,149,789 @satoh_fumiyasu

@_kauplan う…記憶違い、もしくはそのようなシェル実装があったかもしれません。(Solaris 10 の /bin/sh を試そうとしたがブートできなくて試せない…) twitter.com/Hiroki_Sato/st… 参考までに雑なまとめ。 togetter.com/li/1104655 #シェル芸

2019-12-25 11:57:30
Hiroki Sato @Hiroki_Sato

-eはデバッグの補助に使うのは便利ですが、直感的でない動作がたくさんある(関数の中で動かないとか)ので、それを前提としたスクリプトを書くのはやめましょう。

2017-01-28 11:17:08
カウプラン機関極東支部@アルビオン王国民 @_kauplan

@Hiroki_Sato @satoh_fumiyasu -e オプションのあり・なしで実行してみましたが、違いは見られませんでした。また勘違いしてる点があれば指摘いただければとおもいます。 pic.twitter.com/4q8Ysd4o65

2019-12-26 14:14:01
拡大
Hiroki Sato @Hiroki_Sato

@_kauplan @satoh_fumiyasu 「"&& echo..." を外した時の挙動が」と書きました。 わたしが -e を嫌う理由は、単に最初のfalse実行時点で止まらないのが気持ち悪いというだけです。関数の内部で止まる・止まらないが呼び出し方法によって変わるので、関数内のエラー処理がとても書きにくい。

2019-12-27 10:35:06
Hiroki Sato @Hiroki_Sato

@_kauplan @satoh_fumiyasu SUSにそういう動作にしろとありますから、矛盾でもバグでもありません。すべて主観ですので、気持ち悪くないなら気にしなくて良いのではないでしょうか。この仕様のせいで複数人が保守するスクリプトに不具合が生じた経験があるので、エラー処理は面倒でも手で書く派です。

2019-12-27 10:35:25
Hiroki Sato @Hiroki_Sato

@_kauplan @satoh_fumiyasu ちなみにSolarisのshは-eを付けて f() { false; echo a; false; echo b; } f && echo c とすると、2番目のfalseで止まるという謎挙動をします。

2019-12-27 10:36:30
ふみやす@シェルまおう(自称でない) FGO:838,149,789 @satoh_fumiyasu

@Hiroki_Sato あー、たぶんそれかもしれません、私が見たのは。Solaris 10 の /bin/sh はいろいろと POSIX 未満だったり謎挙動するので厄介でした。そろそろ EOL みたいだし、もう無視してよいかと。(ちなみに Solaris 11 の /bin/sh は ksh93)

2019-12-27 11:11:05
ふみやす@シェルまおう(自称でない) FGO:838,149,789 @satoh_fumiyasu

それはともかく世の中のシェルスクリプトの多くにエラー処理が少ないのは確かだと思う。調査したわけではなくただの印象だけどね。 対話シェルとして使うなら雑に使ってエラーが出ればその都度対処してればいいけど、スクリプトとなると別なのに、対話シェルのときと同じ意識で書いてしまってる?

2019-12-29 23:39:19
ふみやす@シェルまおう(自称でない) FGO:838,149,789 @satoh_fumiyasu

シェルのワード分割やパス名展開なども雑に理解するだけでもいい感じに便利に使えてしまうのだけど、ちゃんと理解しないと危ないよ。そこまで理解してシェルスクリプトを書いている人が少ないのだろうね、きっと。

2019-12-29 23:42:32
Hiroki Sato @Hiroki_Sato

@satoh_fumiyasu エラー処理書くのが難しいというのもあると思いますが、長い and/or 部分再利用するスクリプトが書かれることが少ないせいかなあ、と。Perlスクリプトも昔CGIで流行った時にエラーチェックしないものなんて山ほどありましたし、シェルスクリプト特有ではないような気がします。

2019-12-30 04:32:01