コマンドライン引数を一々手動で与えて一々実行するのが面倒臭いからシェルスクリプトを書いて走らせるのは良いんだけど,そのシェルスクリプトにもコマンドライン引数を与えたくなるケースってたまにあるよね.
んで他のシェルスクリプトを繰り返し実行するためのシェルスクリプトを書くのって何だか気が引けるよね.1 つのファイルにまとめて書こうと思えば書けるやろ,って.
ってことでそんな風に書き直すと,今度は 1 つにまとめる前のスクリプトで処理してた部分だけを実行したいっつーケースが後になって出てきたりするよね.
それだったらまとめる前と後の両方のスクリプトを残せば良くね ? と一瞬考えるけど,同じ処理をするものが複数存在すると修正する時に二度手間になるし,片方を修正し忘れるっつー下らんミスの発生確率が飛躍的に高まるよね.
…と考えてみると,第二段落の変なこだわりじみたものが邪魔だなぁ.列記してみるとよく分かる.
Pakuchan
割と同じ道を歩んでますな...
そして気づく.スクリプトを書くためにググるなどして時間を費やしている自分に...
とはいえ,無駄にならない時間(身に付く)のでもちろんok
> 今度は 1 つにまとめる前のスクリプトで処理してた部分だけを実行したいっつーケース
ある.あります.超あります.
そんなときはやっぱりそれぞれ別スクリプト.
> 第二段落の変なこだわりじみたものが邪魔だなぁ.
邪魔ってことはないかなぁ.シェルスクリプトは1箇所に固めてあると結構見通しがいいので.
同じファイルにするために別スクリプトに相当する部分を function を使って書いてみたり(さらにvimのfoldingで畳んでおく).
# もちろん実験に関係のない(実験以外でも使えるような)ツール用のシェルスクリプトは単独の別ファイル.
# functionの場合,別ファイルにしたときと違ってサブシェルが起動しないので高速,という副次的な効果も.
# そういえば,俺は何を思ったか,自分の研究で「シェルスクリプト無しで動くようにしよう」とか思って
# シェルスクリプト相当の反復動作を全部プログラムで書いたんだよね... あんなことは二度とやるまい.
最後に経験上のしょーもないアドバイスを1個.
「進捗報告の実験に使ったスクリプト(とプログラム)はその当時のありのままの姿で保存しておいたほうがいいかも」
というのは,過去の進捗報告書に載せた結果をもう一度出そうとして,同じようにやったつもりが違う結果が出た,という恐ろしい経験があるもので...
# 当時の進捗報告書を読めば,「どうやって結果を出したか」が書いてあるはず.
# ところが,当時の自分が書いた報告書を読むと,書いてない (無くてもわかるだろうと思って省略したか,あるいは記述ミス)...
# こんなときに助けとなるのは,結果を出したスクリプトそのもの.
# しかし,実験用シェルスクリプトも散々書き換えた後で,どこをどう変えたかも覚えていない... (ちーん)
単純に自分が悪いんですが...
まあ,このような失敗をしないように,実験用スクリプトもプライベートリポジトリに入れておくのが吉,というアドバイスです.
y_iihoshi
これまで極力 1 つのファイルにまとめてたのには それなりの理由があったことを思い出しました.
「function から呼び出し元への値の受け渡しにグローバル変数を使う」
うっぎゃあああですね.通常では考えたくもないですね.
以下のような書き方ができることを実は今日になって初めて知って,更にうっぎゃあああですね.
function myfunc { echo "arguments: $@"; }
var=`myfunc abc 123`
echo "var = $var"
# 「var = arguments: abc 123」と出力される
これを多用すれば今後はより smart に書けることでしょう….
> 過去の進捗報告書に載せた結果をもう一度出そうとして,同じようにやったつもりが違う結果が出た
あぁ〜,言われてみればそんな報告を聞いた覚えがありますねぇ.今思い出しました.
> 実験用スクリプトもプライベートリポジトリに入れておくのが吉
いやはや,同じ道を歩んでますねぇ…w
# 俺が真似をしてる というのも多少あるでしょうけども.
Pakuchan
そうだそうだ.思い出した.
一番悩むのが,実験スクリプトの中断・再開.
まず,俺がB4だった頃の話.
スクリプトによる実験は何かと中断することが多かった... (スクリプトのバグがほとんどですが)
かといって「長い実験を最初からやり直すようなスクリプト」にはしたくないので...
→ test -f "xxxxx" なんかを使って出力ファイルの有無によって実験を行うかを判定していたのが最初の頃.
→ SIGINT, SIGTERM 等で出力ファイルを消すようにシグナルハンドラも途中で付け加えてみたり.
でもそれだと... 再実験したい実験のファイルを消す必要がある.
→実験のファイルは非常に奥深くに存在.辿るのが面倒(変化パラメータの値ごとにディレクトリ階層がある).
→しかも消し忘れる可能性大.
そこで第2段階.実験パラメータファイルの更新時刻と出力ファイルの更新時刻を比較して実験の必要性を判定.
→ test A -nt B を随所に追加するも途中で挫折.makeで書き直したほうがいいけどやらなかった.
そして M2 の頃...
結局,実験するパラメータと範囲をシェル変数(もしくは引数)に与えてからスクリプトを起動することに...
すなわち,
USE_PARAM="sigma"
PARAM_sigma="0.0 0.2 0.4 0.6"
てな具合に.たとえば sigma=0.4 の実験以外をやりなおしたければ,
PARAM_sigma="0.0 0.2 0.6"
という風にしてました.
... 結局人力(入力でもλ力でもありません).世の中人力ほど強いものはないのかねー.
プロコンの競技部門の話し合いでも「勘」という人力を使おうかという話が出るわけですし.
もとい,人力とはいっても,最初に書いたファイルを消すやり方よりは遥かに簡単なので割と良かったです.
で,俺は結局この問題を解決することなく修了しちゃいました.てへ.
y_iihoshi
> 世の中人力ほど強いものはないのかねー.
臨機応変に対処するにはまだまだ人力が一番 という事なんでしょうねー.
となると,人力で対処すべき箇所を如何に極限まで削減するか,という話になるんでしょう.
今 Pakuchan さんの実験用スクリプトを見てみました.
これ,第三者が全体を把握して駆使するに至るまでにはちょっと時間が要りますねw