BLOGTIMES
» ArchiveList (Tag for "linux / ruby" )
«Prev || 1 · | Next»
2014/03/13

ls -f と Dir.glob()

linux  cli  ruby 

Linux などで ls -l とするとファイル名はきちんと辞書順で表示されるのに、他のプログラムでディレクトリをなめると出てくる順番がバラバラになるということにはずっと前から気になっていました。例えばタイムスタンプや日付でファイルを生成して、古い方から逐次処理しているつもりが・・・・・・というバグを出してしまったこともあります。

そんなちょっと不思議な挙動の理由がやっと分かったのでメモ。例えば find コマンドの結果やRuby のプログラムで Dir.glob() を使ったりすると下記のような結果になります。

$ mkdir bbb $ mkdir ccc $ mkdir eee $ ls bbb ccc eee $ find . -mindepth 1 -type d ./eee ./bbb ./ccc $ ruby -e 'puts Dir.glob("*")' eee bbb ccc

これについては下記のエントリで ls のソースコードはもちろんのこと、 strace による解析や Perl の内部構造についても詳細に解説されています。これはとても良い教材になりそうです。結論としては ls がデフォルトで、ls が出力結果をソートするようになっているだけということのようです。ちなみにこのソートは -f オプションをつけるとオフにできるとのこと。

ls のソースを読んでプログラマになりました - ablog

こちらも getdents を呼んでいる。Perl の readdir も ls も getdents システムコールを呼んでるけど、ls はソートしていると思われる。ls の man を見ると、デフォルトでアルファベットでソートされ、-f オプションをつけるとソートされないと書かれている。
ls に -f オプションをつけると Perl の readdir と同じ順になった。

試しに ls に -f をつけてみると、find や Dir.glob() の結果と同じになりました。
まだまだプログラマとしては青いことを痛感させられますね。


    at 22:12 |
    2009/11/21

    crontab -r とやってしまった時の対処法

    linux  sh  ruby 

    cronの設定を変えようと crontab -e と打とうとして、間違って crontab -r と打ってしまい、cronの設定が根こそぎぶっ飛んで参りました。「eとrは隣同士だから不慮の事故ですよ!」という他人の言い訳は以前から良く聞いていて、心の中で「そんなことあるかよ!」と思っていましたが、まさか自分がやってしまうとは思いませんでした。まったく言い訳できません

    そして、こういう事故は絶対やってはいけないアカウントでやってしまうのが世の常。今回も例に漏れずたくさんジョブが仕込んであるアカウントでやってしまいました。しばし茫然自失。気を取り直してなんとかしようと考え始めたものの、さすがにこれを記憶に頼って復旧させるのは至難のワザ・・・・・・というかぶっちゃけ無理。適当に復旧してちゃんとバッチが動かずに、後日障害で呼び出されるものイヤです。

    済んでしまったことでくよくよしていても仕方が無いので、手動での復旧はあきらめ、/var/log/cron の実行ログからcrontabをサルベージする*1スクリプトを書いてみました本当は時刻の設定とかも復元できるようにしようかと思ったのですが、まぁそんなにお世話になることもないのでそのあたりは手動で実施するということにします。いちおうリストアップされるようにしました。ユニークに出力する(*/5みたいに綺麗に畳んだりできない)ので出力は結構冗長ですが、そこは勘弁してください。

    $ ./cron_salvage.rb --help Usage: cron_salvage [options] -f, --file CRONLOG cron log file (default: /var/log/cron) -u, --user USER cron user (default: root)

    こんな感じで、対象のログファイルとユーザーが指定できるようにしてみました。
    /var/log/cronが読める必要があるので、基本的にはrootユーザーで実行する必要があります。

    $ ./cron_salvage.rb * * * * * /usr/lib/sa/sa1 1 1 * * * * * ionice -c3 nice -n 19 /opt/apache/htdocs/admin/AWStats69t_Jpn/wwwroot/cgi-bin/awstats.cron > /dev/null 2>&1 * * * * * run-parts /etc/cron.daily * * * * * run-parts /etc/cron.hourly * * * * * run-parts /etc/cron.weekly

    こんな感じで、crontabが復元されるので、cron.(daily|hourly|weekly)に設定されている部分など、不必要な部分を除いてやればよいと思います。まぁ、対象がrootでなければ余計なものはあまり出てこないと思いますが。

    [crontab -r とやってしまった時の対処法 の続きを読む]
    • *1: ちなみにこの方法は僕が考案したわけではなく、以前にとあるプロジェクトで同様の事故が起きた際にある人が考えついた方法です。そのときは手動でやっていたのを脇目で眺めているだけでした。

    at 20:27 |
    «Prev || 1 · | Next»
    » ArchiveList (Tag for "linux / ruby" )