タグ

ブックマーク / blog.bsdhack.org (8)

  • Mitzyuki's Blog :: シェルスクリプトで便利な小技

    シェルスクリプトで便利な小技 シェルスクリプトを作成するときに知っておくと便利な小技集。 exec > ファイル 以降の標準出力を全て ファイル に出力するので この設定をしておくと簡単な実行ログが取得出来る。 同様に exec 2> ファイル とすると 標準エラー出力が全て ファイル に出力されるので エラーログが取得できる。 当然 exec > ファイル 2>&1 とすれば 標準出力も標準エラー出力も取得できる。 ファイル に /dev/null を指定すれば スクリプト実行中の出力は全て抑止されるので、 cron (8) から実行される場合などでは便利な場合もある。 1#!/bin/sh 2 3exec 2> ${TMP:-/tmp}/myname.log 4 : set -e スクリプト実行時に制御文以外でエラーが発生した場合に スクリプトを終了させる。 スクリプト中で実行すべきコ

    masutaka26
    masutaka26 2012/07/29
    ありがとうございます。
  • Mitzyuki's Blog :: posix shell で標準入力同士の <i>diff</i> (1) を実現する方法

    posix shell で標準入力同士の diff (1) を実現する方法 コマンド command1 の出力結果と コマンド command2 の出力結果を diff (1) で比較したい場合、 一番手軽なのはそれぞれの出力を一時ファイルに出力して比較する方法である。 $ command1 > ${TMP:-/tmp}/output1 $ command2 > ${TMP:-/tmp}/output2 $ diff ${TMP:-/tmp}/output1 ${TMP:-/tmp}/output2 : $ rm ${TMP:-/tmp}/output1 ${TMP:-/tmp}/output2 しかし、この方法では一時ファイルを作成するので 処理効率が悪く一時ファイルの削除など後処理をする必要がある。 例えば bash (1) の場合は以下の様にする事で簡単に比較できる。 $ diff

    masutaka26
    masutaka26 2012/06/18
    おぉすごい!出来た。2 番目の方法は zsh でも使えた。
  • Mitzyuki's Blog :: コーディングスタイル

    コーディングスタイル 自分のコーディングスタイル晒しの続き。 空白 linux コーディング規約とは若干異なっている。 基的に余計な空白はなるべく入れない様にしているので、 if、switch、case、for、 do、while の後ろに空白は入れない。 それ以外は linux コーディング規約とほぼ同様だと思う。 2 項演算子や3 項演算子の演算子の前後には空白を入れるが、 例外的に for 文の中では演算子の前後に空白を入れていない。 /* 2 項演算子 */ i = j * 2; /* 3 項演算子 */ x = x < y ? x : y; /* if 文 */ if(condition) do_condition(); /* for 文 */ for(i=0; i<max; i++) do_loop(); 名前の選択 これも linux コーディング規約に賛成。 例えばループ

    masutaka26
    masutaka26 2012/06/08
    goto 賛成です。でも免許制にした方が良いかもw
  • Mitzyuki's Blog :: コーディングスタイル

    コーディングスタイル 世の中にはプログラマの数だけコーディングスタイルがあると思うけど、 Linux カーネルのコーディング規約 と対比しながら、自分のコーディングスタイルを晒してみる。 勿論これはスクラッチで自分が自由に作成出来る場合のスタイルであって、 プロジェクトなどによりコーディング規約が定まっている場合や 他人が作成したソースを修正する場合は基的にはそのスタイルに合わせる。 インデント linux コーディング規約とは完全に意見を異にするが、 基的にタブは 4 文字にしている。 通常の 80 カラムのディスプレイで見たときに タブが 8 文字だと間延びして見えてしまう事と、 ネストが 3 段以上になると格段に見づらくなる事が主な理由。 勿論、「3 段以上のネストは悪い」という意見は 原則的に賛成だが、 そうは言っても実際はもっと深くネストする事が 避けられない場面も多々ある。

    masutaka26
    masutaka26 2012/06/08
    if の後ろは単文でも必ずブレース(波括弧)を付けるかなあ。ブレースを付け忘れてなんとなく動いているソースを見たことがあるので。。私はやらないですけど、if を改行せずに書いた方がまだマシかな。
  • Mitzyuki's Blog :: shell での while ループにおける問題

    shell での while ループにおける問題 シェルスクリプトでコマンドの出力をループ処理する場合は パイプ | を使用するのが一般的な手法だと思うが、 パイプ | を使うとループが別なプロセスとして実行されるので ループ内部で設定したシェル変数がループ外部で参照できないという問題があり、 (存在するとすれば) shell script 業界では割と FAQ 的な問題だ。 何が問題かと言って posix で定義されていないから シェルの実装に依存しているのが一番の問題だったりするのだろう。 この問題に対しては、シェルビルトインの exec (1) を利用して ディスクリプタを複製して while ループの入力を標準入力にしてしまうのが 一番汎用的で柔軟性のある対応だと思うのだが、 シェルを愛する面々は 皆同じ様な苦労をしているのだ と改めて認識した。 当初は一時ファイルを作成する方法を

    masutaka26
    masutaka26 2011/11/25
    ここまで突き詰めて考えるのはすごいなあ。私だったら Ruby に逃げちゃうw
  • Mitzyuki's Blog :: シェルスクリプトで疑似乱数を取得する

    シェルスクリプトで疑似乱数を取得する gnu bash には ${RANDOM} というシェル変数が用意されていて、 アクセスするたびに疑似乱数(風)の値が取得できる様だ。 しかし posix 準拠の機能ではなく bash 独自の機能なので拡張性がない。 そこで汎用的な疑似乱数取得の方法として awk (1) を利用した方法を使ってみる。 awk (1) には rand() という関数が組込まれているので 乱数生成ができる。 その際に利用される種(seed)は srand() という関数で初期化できるので、 これらを利用する事でそこそこの精度の疑似乱数は取得できる。 たとえば 0 〜 m までの疑似乱数は 取得した値から m の剰余を取ることで取得できる。 ただし awk (1) の rand() は仕様として 0 〜 1 までの桁数不定の少数を返すので、 乱数として利用する場合には整数に

    masutaka26
    masutaka26 2011/11/24
    Bourne Shell でランダム変数を使う方法
  • Mitzyuki's Blog :: grep & awk

    grep & awk grep "^HOGEHOGE" file | awk 'BEGIN { FS = "="}; { print $2 }' というコード。一見何も問題ない様に見えるし確かに動作はするが、 CPU とプロセスと時間の無駄遣いである。 awk (1) には拡張正規表現が実装されているで、 awk 'BEGIN{FS="="}/^HOGEHOGE/{ print $2 }' file とすれば grep (1) の分だけ CPU やプロセス、時間が節約できる。 sed -n '/^HOGEHOGE/s/^.*=//p' file とするのも等価かな。 行指向の処理であれば煩雑な awk (1) よりも sed (1) の方が見やすいので、 個人的には sed (1) を利用した方法がお勧め。 シェルスクリプトに限らずスクリプト言語で記述されたプログラムは、 source f

    masutaka26
    masutaka26 2011/11/24
    grep&awk は awk や sed のみで書けるという話。その他、無駄のないスクリプトの書き方。
  • Mitzyuki's Blog :: ファイルのオーバーライド

    ファイルのオーバーライド 通常のパイプ動作するフィルタコマンドでは 元ファイルを直接オーバライドできない。 例えば sort (1) の -o オプションの様に 元ファイルのオーバライド指定ができる (この動作をスポンジ動作というらしい)もの以外での処理について。 一番簡単で誰でも思いつくのが一時ファイルを利用するやりかた。 $ command < foo.dat > foo.new $ mv foo.new foo.dat この方法だと command の実行中に割込が発生したりすると 一時ファイルが残ってしまい美しくない。 $ cat foo.dat | ( sleep 1; command > foo.dat) この方法だと sleep (1) の時間がうっとおしく、 データ量や command の速度などによって失敗する場合もありうる。 $ (rm foo.dat; command

    masutaka26
    masutaka26 2011/11/24
    元ファイルをオーバーライドする方法。正直よく分からないけどすごい。。
  • 1