わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

gcc -Wallでコンパイルして,成功すれば引数つきで実行するfunction

コンパイルのコマンドを打ち込んで,成功すれば実行して,論理エラーがあればプログラムを修正して,上矢印2回でコンパイル,上矢印2回で実行,…というのは手間です.たまに,コンパイル時にエラーが出ることもありますし*1
コンパイルコマンド && 実行コマンド」を実行するようにすれば*2,上矢印1回で済むのですが,それでも打ち込むのが面倒です.
そこで,functionを書きました.Cygwinzsh 4.3.9のほか,Ubuntu Linux*3 Debianbash 3.1.17でも動作を確認しました.

function Wall() {
    local src bin bin_com com1 com2

    if [ $# = 0 ]
    then
	return 1
    fi

    case $1 in 
	*.c) src=$1; bin=${1%.c} ;;
	*.)  bin=${1%.}; src=${bin}.c ;;
	*)   src=${1}.c; bin=$1 ;;
    esac
    shift
    case $bin in
	/*) bin_com=$bin ;;
	*)  bin_com=./$bin ;;
    esac

    com_cc="gcc -Wall -o $bin $src"
    com_exe="$bin_com $@"
    echo $com_cc '&&' $com_exe
    $(echo $com_cc) && $(echo $com_exe)
}

引数には,「.c」つきのファイル名でも,「.c」なしでもかまいません.すなわち,「Wall program.c」と書いても「Wall program」と書いても,「gcc -Wall -o program program.c && ./program」を実行します*4
さらに,Wallコマンドへの2番目以降の引数は,実行する際の引数にしました*5.「Wall program abc def」なら「gcc -Wall -o program program.c && ./program abc def」になります.
完成まで,いろいろ苦労がありました.まず,Wallコマンドへの引数がないときのチェックで,当初「if [ ! ${+1} ]」と書いていましたが,これはbashだとダメのようです.「$#」が引数の数になることを知り,「if [ $# >= 1 ]」とか「if [ $# > 0 ]」とか書くと失敗.イコール以外の比較演算子は,true/falseではなく1/0になるようです.ということで,「if [ $# = 0 ]」に落ち着きました.
通常,コマンドラインでのコンパイルは,カレントディレクトリのファイルに対して行いますが,まあ他のディレクトリにあってもいいかなと,手を加えています.具体的には,実行ファイル名にはbin,実行コマンドにはbin_comと分けました.実行ファイル名の先頭が「/」であれば,実行コマンドもそのままとし,そうでなければ,「./」を先頭につけます.なお,ホームディレクトリのチルダ展開は,Wallを処理する前に行われるので,「~」から始まるファイルも,問題なくコンパイル・実行できます.
Wallの先頭が大文字で,打ち込むときに面倒なら…

alias wall=Wall

ですね./usr/bin/wall*6なんて使いませんし.

*1:かといって,統合開発環境に乗り換えると,そういうのがないところでコンパイル・実行するときにまた大変になりますね.

*2:上矢印連打を減らそう - わさっき

*3:同日9:30ごろ修正.動作確認マシンを勘違いしていました.なお,Ubuntubash 3.2.39でも,うまくいきました.

*4:Cygwinでは,実行ファイルに「.exe」がつきますが,幸い,「.exe」を書かなくても実行できるので,期待通りに動作します.

*5:これを実現しているのが,上記functionの中の「shift」と「$@」です.

*6:http://x68000.q-e-d.net/~68user/unix/pickup?wall