シェルスクリプトにシバン(#!/bin/sh)はないほうがいいという説
あとは,toyboxとか。似たようなのが他にもあるかもしれない。 BusyBoxのshellはash。環境を手元に用意しておいたほうがいいか。 What is toybox? landley.net/toybox/about.h…
2017-02-02 21:32:15Androidには標準で/system/bin/にtoolboxというbusyboxみたいなのが入っているのか。しらなかった… toolbox ‐ 通信用語の基礎知識 wdic.org/w/TECH/toolbox
2017-02-02 22:04:20PATHの初期化決着
以下のように2段階でやれば解決
PATH="$(command -p getconf PATH 2>&-):/bin:/usr/bin${PATH:+:}${PATH:-}"
export PATH=${PATH#:}
@senopen busyboxのashでもcommand -pvが使えるか試したら、ダメだった。帰宅したらkshとかでも念のため確認してみるか… command -pvはやめたほうがいいのだろうか…
2017-02-03 09:26:59@senopen ashはFreeBSDの/bin/shでもあるので、FreeBSDでも試してみたところ、 $ command -pv getconf PATH command: wrong number of arguments $ となり、通じないOSがさらに一つ確認された
2017-02-03 10:08:25@senopen ksh88(AIXの/bin/sh)で同じコマンド実行したら、 sh: command: bad option(s) と表示されて失敗した。ksh93(AIX)とpdksh(ksh93ベースのOpenBSDの/bin/sh)では成功した。
2017-02-03 10:36:26@col_richie 調査ありがとうございました。 さすがに影響範囲が広いので無視できませんね。幸いなことに、command -pvを使わずにgetconfがあれば実行してPATHを取得する最短記述方法が思いついたので大丈夫そうです。昼休みに続きを書きます。
2017-02-03 10:57:58以下のように常にエラーを無視すれば大丈夫です。 ついでにgetconfのない環境用に、/bin:/usr/binを追加。 export PATH="$(command -p getconf PATH 2>&-):/bin:/usr/bin:$PATH" @col_richie
2017-02-03 12:21:03@col_richie 根拠はFHS。sbinはシステム管理者用コマンドなので不要だと判断。 この先、androidやiOS対応もするなら、シバン#!/bin/shと一緒に外します。シバンの根拠がFHSなので、シバンをつけるなら、一緒につけても問題ないと判断しました。どうでしょう
2017-02-03 14:21:31@senopen なるほど、それなら説明がつくな。>FHS そういえばPATH文字列の中に、空パス(":〜"や"〜::〜"や"〜:")とか存在しないパスが指定されていても正しく動くことは保証されているかな?まぁ動かない事例は聞いたこともないし、動かない環境の方が非実用的に思えるし
2017-02-03 14:31:44@col_richie 空パスの扱いについては、XBDのenvironmenral variableのPATHの説明で書いてあった記憶があります。帰宅したら確認してみます。
2017-02-03 14:34:28@senopen XBDのその場所を読んだところ、空パス(ずばり":〜"や"〜::〜"や"〜:"を示している)は、カレントディレクトリーと見なすらしい。うーむ、これは厄介。
2017-02-03 14:46:46@senopen 空パス問題解決方法。 PATH="$(command -p getconf PATH 2>&-):/bin:/usr/bin${PATH:+:}${PATH:-}" export PATH=${PATH#:} というように、二段階にすると何とか解決できる事を発見
2017-02-03 16:42:27@senopen ${PATH:+:}というのが最初の工夫。":+"は元変数が未定義または空の場合に空文字を返すが何か入っていれば":"を返す。つまりPATHに何か入っていれば、元のPATHの中身の手前に$(〜)を付け足す時に自動的に":"が付くという。次の工夫は二段目の"#:"
2017-02-03 16:46:23@col_richie うまいですね!なるほど。:+はおもいつきませんでした。素直にsedを考えていました。 既存のPATHに含まれる、空:や., ./もカバーすべきなんでしょうかね…だとしたら結局sedが必要で、長くなってしまいますが…。
2017-02-03 18:09:33@senopen 既存の$PATHに入っているものはそのままでいいのではないかなぁ。こちらのプログラムが必要としているパスは手前に付けてしまうし、元々空パスついていれば意図的なのかそうでないか判断する術もないし、sedも必要になってしまうし……
2017-02-03 21:10:52@col_richie ああ。そうでしたね。安全なPATHを前置しているから,既存のPATHがどうなっていようが大丈夫という論理でしたね。お騒がせしました。
2017-02-03 21:45:55PATH初期化についての懸念
FHSの/sbinのコマンドがPOSIXに入っていないか確認したのだけど,なかった。 PATHの初期化時に入れるのはやめたほうがいいか。 Filesystem Hierarchy Standard refspecs.linuxfoundation.org/FHS_3.0/fhs-3.…
2017-02-04 16:18:19PATH変数の初期化。自分で/bin:/usr/binを入れたほうがいいと書いたけど,これ入れると,${PATH#:}が必要になり2行。 export LC_ALL='C' PATH="$(command -p getconf PATH 2>&-)${PATH:+:}$PATH"
2017-02-04 16:33:48いらないなら上記のように1行で全部書ける。コードの綺麗さで行くとこっち。だけど,getconfがないとPATHの初期化ができなくて危険。 Androidも対応するなら,長くなるからPATH変数の初期化でもう1行追加して,/usr/local/binも追加して3行でもいいのだけど…
2017-02-04 16:36:22こう PATH="/bin:/usr/bin:/usr/local/bin:/sbin:/system/bin${PATH:+:}$PATH" PATH="$(command -p getconf PATH 2>&-):$PATH" export PATH="${PATH#:}"
2017-02-04 16:39:06