2016年9月19日月曜日

[unix]sleepとusleep

Linuxから他のunixにシェルスクリプトを持っていって、動かないなんてことはたまにある。

例えば、usleepコマンドを使っているスクリプトをBSD系のunixに持っていくとusleepがなくて、動かなかったりする。
Linuxでもモノによってはusleepが初めからは入っていないかもだけど。
# そもそもシェルスクリプトで秒未満の待機なんてするデザインが悪い。ってのはとりあえず置いといて。。。

じゃあ、usleepコマンドがない状態でどうしよっかって考えたんだけど、マニュアルを確認して気づいてしまった。

http://www.freebsd.org/cgi/man.cgi?sleep(1)
BSDではパラメータはstrtodが受け付ける小数でもOKということになっている。
$ uname
Darwin
$ time sleep 0.5

real  0m0.510s
user  0m0.002s
sys   0m0.003s

確かに待機時間が0.5秒になっている。この仕様であれば、usleepコマンドは必要ないかなってのも分からなくはない。

https://linuxjm.osdn.jp/html/gnumaniak/man1/sleep.1.html
Linuxのsleepは最小単位は秒になっている。

https://linuxjm.osdn.jp/html/GNU_coreutils/man1/sleep.1.html
GNU_coreutilsのマニュアルだと、小数の指定もできるよ、ってことになっている。

確かにLinuxでも、小数が指定できるようになっている。
$ uname
Linux
$ time sleep 0.5

real  0m0.503s
user  0m0.002s
sys   0m0.001s

でもsleepコマンドで小数が指定できるのはあくまで拡張仕様であって、移植性を考えると難しいところですね。。。

2016年9月12日月曜日

[シェルスクリプト]シェルスクリプトで関数を使い分ける

シェルスクリプトはインタプリタで1行ごとに順に解釈されていくから、関数を実行する前にその関数の定義が登場しなければいけない。
それはいいんだけど、本当に "実行する前に" ということがどういうことか、ちゃんと分かってなかった。

以下のようにfunc1からfunc2を呼び出しているとしよう。

#!/bin/sh
func1 () {
  echo 'func1'
  func2
}

func2 () {
  echo 'func2'
}

func1

2016年9月5日月曜日

[SQL]SQLでHello, world?

SQLでHello, world.って言ったら、すぐに思いつくのはこんな感じだろうか。

SELECT 'Hello, world.';

いくつかのDBMSではこれでうまくいく。
でも、OracleだとFROM句がないとおこられちゃうよね。

2016年8月29日月曜日

[SQL]with句の効用

[SQL]SQLの共通表式ではSQLのwith句でテストデータの生成ができるってことを書いたけど、それ以外にもwith句には効用がある。

・サブクエリにコメントを付けておこう。
SQLだと他のソースコードに比べて、コメントがおろそかになっていることが多いけど、サブクエリ毎にコメントを付けておくとわかりやすいんじゃないだろうか。

サンプル用のテーブルはこんな感じ。
IDをキーにして、開始日と終了日を持っているとしよう。

Periods
ColumnType
idChar(5)
start_dayDate
end_dayDate

2016年8月22日月曜日

[C]オペークポインタ

「いくつかの言語でフィボナッチ数生成」を考える。ではハンドルに配列そのものを使っていたけど、CのAPIでハンドルを使う場合はオペークポインタにすることが多いよ。

「いくつかの言語でフィボナッチ数生成」を考える。の結果をオペークポインタを使ったものに変えてみよう。
まずは呼び出し側を見てみよう。

main.c
#include <stdio.h>
#include "fib.h"

int main(void) {
    hSequence fib = fibonacci_new();

    for (int i = 0; i < 10; i++) {
        printf("%d\n", fibonacci_next(fib));
    }

    fibonacci_delete(fib);

    return 0;
}

2016年8月15日月曜日

[Java]Mapのループ

JavaでMapをループする時に、なんとなしにkeySetを使ったりしていた。

MapIterate1.java
import java.util.HashMap;
import java.util.Map;

class MapIterate1 {
    public static void main(String ... args) {
        Map<String, String> map = new HashMap<>();
        map.put("banana", "yellow");
        map.put("apple", "red");
        map.put("orange", "orange");

        for (String key : map.keySet()) {
            System.out.println(key + ":" + map.get(key));
        }
    }
}

けれど、パフォーマスを考慮するとentrySetを使ってループしたほうがいいみたい。

2016年8月8日月曜日

[bash]キャリッジリターンの使いどころ

Unixの改行コードはLFでWindowsの改行コードはCRLFだ、なんていう話はよく出てくる。

CR(carriage return)というのは本来、現在位置を行の先頭に戻すだけで次の行には進まない。
LF(line feed)は逆に行中の位置は変えずに現在位置を次の行に進める。

じゃあ、CRのみを使うのはどういった場面があるだろうか。
例えば、コマンドラインで進捗状況を表示することを考えよう。

count.sh
#!/bin/sh

for i in $( seq 10 )
do
  # \rで行の先頭に戻ってから出力、改行はしない。
  printf "\r%2s/10" $i
  sleep 1
done
echo ''