出力を入力へ

プログラミングに関する自分が考えた事を中心にまとめます

引数を利用しない場合でも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