echo
1) Cygwinを起動します。

2) ソースを格納するディレクトリに移動
cd src でソースを格納するディレクトリに移動します。
3) ソース作成
カレントでviエディタを起動して myecho.c を作成します。(Windowsのメモ帳などで作成してこのフォルダに保存してもよいです)内容は下です。
#include    <stdio.h>
#include    <stdlib.h>

int main(int argc, char ** argv)
{
	int     i;

	for(i = 1; i < argc; i ++) {
		if(argv[i][0] == '$') {
			printf("%s", getenv(& argv[i][1]));
		} else {
			printf("%s", argv[i]);
		}
	}
	return 0;
}
4) インクルードファイル
printfを使っているのでstdio.hを、getenvを使っているのでstdlib.hをインクルードします。
5) mainの引数
mainは引数をとらないか(void)もしとる場合は第1引数はint、第2引数はchar **と(C言語の仕様で?)決まっています。argc、argvの変数名は何でも良いですが慣習でこれらの変数名を使っています。普通はこれらの変数名を使うようにします。argc、argv にはプログラムを起動したときのコマンドラインの引数の情報が格納されています。argc には引数の数、argv には文字列が格納されています。例えば myecho 123 $PWD と入力された場合は下のように格納されています。
変数 説明
argc 3 int 起動されるプログラム名も含めて引数は3個です。
argv アドレス char ** ポインタ配列の先頭のアドレス
argv[0] "myecho"のアドレス char * 0番目にはプログラム名が入っています。
argv[1] "123"のアドレス char * コマンドラインの1番目の引数が格納されています。
argv[2] "$PWD"のアドレス char * コマンドラインの2番目の引数が格納されています。
argv[1][0] '1' char コマンドラインの1番目の引数の1番目の文字が格納されている
6) 引数の数分ループ
for(i = 1; i < argc; i ++) で2番目の引数から最後の引数までループさせ、一つ一つの引数について順番に処理します。
7) 変数か文字列かの判断
if(argv[i][0] == '$') は各引数の先頭の1文字をみて変数か文字列か判断します。"123"の先頭は'1'なので文字列と判断してそのまま表示しています。"$PWD"の先頭の1文字は'$'なので変数と判断して、getenv関数で対応する値を取得して取得した値を表示しています。
8) 実行
プログラムを実行してみます。(実行の前にコンパイルしてプログラムを作成しておきます)
Owner@FMIL002 ~/bin
$ myecho 123 $PWD
123/home/Owner/bin
コマンドラインの引数の123は文字列と判断されそのまま表示され、$PWDは変数と判断されその値(/home/Owner/bin)が表示されています。

9) exportコマンドとの関連
例としてexportコマンドで変数を登録してからmyechoで表示させてみます。
Owner@FMIL002 ~/bin
$ export MYTEACER=nyankosensei

Owner@FMIL002 ~/bin
$ echo $MYTEACER
nyankosensei
10) アドレスを表示
プログラムを変更してアドレスや値を表示してみます。
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>

int main(int argc, char ** argv)
{
	int	 i;
	int	 j;

	/* DEBUG OUTPUT */
	printf("address	  value \n");
	printf("(%p) argc=(%d)\n", & argc, argc);
	printf("(%p) argv=(%p)\n", &argv, argv);
	for(i = 0; i < argc; i ++) {
		printf("(%p) argv[%d]=(%p)(%s)\n", & argv[i], i, argv[i], argv[i]);
	}
	for(i = 0; i < argc; i ++) {
		for(j = 0; j < strlen(argv[i]) + 1; j ++) {
			printf("(%p) argv[%d][%d]=(%c)\n", & argv[i][j], i, j, argv[i][j]);
		}
	}

	for(i = 1; i < argc; i ++) {
		if(argv[i][0] == '$') {
			printf("%s", getenv(& argv[i][1]));
		} else {
			printf("%s", argv[i]);
		}
	}
	return 0;
}
        
4節 gccでプログラム生成  echo 4節 gccでプログラム生成