本番では、運良くEasy, Medが素早く解けたが結局Hardは方針すら立たなかった。
とはいえ、まったく手が出ない問題ではないので
将来的にはこのような問題は解けるようになりたい。
Visual Studioにおけるビルド・リビルド・クリーン
最近、WindowsにてOfficeアドイン開発をしていた時に気付いたこと。
一般に予測される挙動とちがったのでメモ。
引数を利用しない場合でもWarningを出さない
いまさらながら知ったこと。
C言語プログラミング時にコンパイルオプションにWallを指定するなど、
利用していない引数がある場合に警告を出している。
通常はこれば便利だけども、どうしても避けられない場合もある。
これを解決する方法として、-Wno-unused-parameterを使うことで
利用していない引数があっても警告を出さないこができるが、
コンパイル単位でしか指定できないという欠点がある。
関数ごとに解決する方法として以下の方法がある。
void func(int x) { (void) x; .... }
もしくは、もっとわかりやすく
#define UNUSED(x) ((void)x) void func(int x) { UNUSED(x); .... }
このように関数内で指定することで、
以降の処理で引数を参照しなくてもWarningが出なくなる。
わざわざコンパイル単位で無効にする必要がなくなるので便利。
標準出力を変数に代入する方法あれこれ
シェルスクリプトにおいて標準出力(標準エラー出力)される文字列を変数に代入して取り扱う方法について。
対象とする関数として以下のものを利用。
sayHello(){ sleep 10 echo "hello stdout" echo "hello stderr" >&2 }
直接変数に代入する
変数messageに出力を代入したければ以下のようにすればよい
message=`sayHello` echo ${message}
この結果は以下の通り
hello stderr hello stdout
つまり、関数"sayHello"実行時にエラー出力が表示され、
標準出力は変数messageへの代入を経由して出力される。
これではエラー出力結果を別の変数に代入することはできない。
また、関数"sayHello"をバックグラウンドで実行したい時には
標準出力を変数に代入することができない。
ファイルを経由して代入する
標準出力と標準エラー出力の内容をファイルにリダイレクトし、
それぞれのファイルを変数に展開することでこれを解決する。
sayHello > /tmp/message.out.$$ 2>/tmp/message.err.$$ message_out=`cat /tmp/message.out.$$` message_err=`cat /tmp/message.err.$$` rm -f /tmp/message.out.$$ rm -f /tmp/message.err.$$ echo ${message_out} echo ${message_err}
この結果は以下の通り
hello stdout hello stderr
これにより標準出力、標準エラー出力をそれぞれその後の処理で扱える上に
処理をバックグラウンド化するこことにも対応できる。
ただし、この方法だとディスクアクセスを伴う?
これ以上どうにかしたかったら何らかの別のプログラミング言語を
利用しようってことなのかな。
getoptの使い方
シェルスクリプトで引数処理をしてくれるgetoptが
どうも上手く使えなかったので整理してまとめ。
既に似た情報は山程ネットにあふれているけど
どうも一目でわからなかったので書き直し。
とりあえず使える用なので
他のオプションとかgetoptsとの区別とかは無視。
#!/bin/sh ######################################## GETOPT_ARG_SHORT="acd:e:" GETOPT_ARG_LONG="one,two,three:,four:" ######################################## getopt_template(){ OPT=`getopt -o ${GETOPT_ARG_SHORT} -l ${GETOPT_ARG_LONG} -- $*` echo "opt=${OPT}" while [ -n "$1" ];do case $1 in -a) opt_a=1;shift;; -b) opt_b=1;shift;; -c) opt_c=$2;shift 2;; -d) opt_d=$2;shift 2;; --one) opt_one=1;shift;; --two) opt_two=1;shift;; --three) opt_three=$2;shift 2;; --four) opt_four=$2;shift 2;; --) shift;break;; *) echo "error";return 1;; esac done return 0 } getopt_template $@ status=$? if [ ${status} -ne 1 ] ;then echo "a="${opt_a} echo "b="${opt_b} echo "c="${opt_c} echo "d="${opt_d} echo "one="${opt_one} echo "two="${opt_two} echo "three="${opt_three} echo "four="${opt_four} fi