はじめに
C言語を全く使っていなかったため、久しぶりに使いたくなった。
そこで、Linuxの復習も兼ねて、足し算するだけのコマンドを自作してみる。
※実用性は全くないが。。
コマンドの仕様としては、コマンドラインの第二引数以降の数値の合計値を出力するというもの。
目的
・簡単なものを自作することで、コマンドがどのようなものかをイメージできるようにする。
・Linuxがコマンドを実行する際に参照するPATHの概念を理解する。
上記のため、実装について詳細な説明は割愛する。
環境
・Amazon Linux AMI release 2018.03
※Cloud9です。
手順
1.テスト用のディレクトリを作成
以降はこのディレクトリ下で作業を行っていく。
$ mkdir test; cd test
2.ソースコードファイルを作成
ここではviにしているが、テキストエディタは何でも良い。
$ vi test_sum.c
3.実装
以下のソースコードをコピペ。
#include <stdio.h>
int main(int argc, char *argv[])
{
int sum = 0;
int count = 0;
if (argc < 3) {
printf("ERROR: invalid of arguments number\n");
return 1;
}
/* argv[0]はコマンド自身なので、計算対象からは除外するため、count=1から開始 */
for (count=1; count<argc; count++) {
sum += atoi(argv[count]);
}
printf("%d\n", sum);
return 0;
}
尚、atoiは最上位の桁から変換していき、数字以外の文字を検出した時点で変換を停止させる。
例)"a":変換できるものがないため、0を返す。
"1a3":最上位の1は変換するが、aを検出したため変換を停止、1を返す。
4.コンパイル
gccを使い、ソースコード(test_sum.c)をコンパイル
$ gcc -o test_sum test_sum.c
動作は単純だが、これでtest_sumというコマンドが完成!
5.簡単な動作確認
自作したtest_sumを使用してみる。
以下、いくつかのパターンでお試し。
$ ./test_sum 123
ERROR: invalid of arguments number
$ ./test_sum 123 23456
23579
$ ./test_sum 123 23456 812
24391
大成功!!
※最初のエラーは引数が少ない(3つ未満)の場合に出力しているエラー。
6.PATH設定
このままだと、毎回パス指定("./"のこと)が必要になってしまうため、他のコマンドのようにパス指定なしで動作するように設定していく。
※同じディレクトリにいても指定が必要になる。
6.1.PATHとは
Linuxが実行ファイル(ELF)を実行するときにファイルを探しに行くパスをまとめている環境変数のこと。
LinuxはPATHに設定されているパスを順番に探していき、最初に見つかった実行ファイルを実行する。
※lsとかfindとかが指定なしで使えるのはPATHに置き場所を保存してあるから。
6.2.PATHの設定
PATHなどの環境変数を設定するにはexportを使用する。
以下のコマンドで今いるディレクトリ(カレントディレクトリ)のパスをPATHに登録。
$ export PATH=$PATH:$(pwd)
これで、どのディレクトリにいてもパス指定不要!
シェルを落としたときにこの設定は消えてしまうことに注意!!
6.3.動作確認
適当にディレクトリ移動して動作確認をしてみる。
$ test_sum 1 2 3
6
$ cd ~
$ test_sum 1 2 3
6
$ cd /tmp
$ test_sum 1 2 3
6
大成功!!
これで、以降は他のLinuxコマンドのようにtest_sumコマンドを使用できる。
※足し算するだけだけど。。。
おまけ
lsやfindなどのコマンドのパスを確認する場合はwhichを使用する。
もちろん、作成したtest_sumもwhichコマンドで場所を確認できる。
$ which ls
alias ls='ls --color=auto'
/bin/ls
$ which find
/bin/find
$ which test_sum
~/environment/test/test_sum
修正内容
・タイトルとか内容を少し変更
・PATHについて追記
・既にあるコマンドとの混同を避けるため、名前を変更
・終了ステータスを設定(戻り値を成功時に0、失敗時に1)
@fujitanozomuさんご指摘ありがとうございます!
・目的を追記