フューチャー技術ブログ

オプション付きのオリジナルコマンドを作成しよう

アイキャッチ

Marcel Langthimによる Pixabayからの画像

はじめに

こんにちは、TIGの尾崎です。シェルスクリプト連載の6日目です。

突然ですが、みなさんは「あんなコマンドあったらいいのにな」と思ったことはありませんか。
めったにないと思いますが、せっかくなので本日はオリジナルコマンドの作成方法を記します。
それではいきましょう。

オプションなしのコマンドを作成

手始めに以下のようなシンプルなオプションなしのコマンドを作成します。

  • 引数を標準出力させる
  • 引数がない場合、もしくは引数が複数の場合はエラーを出力させる

シェルスクリプトtestcommandを作成します。
作成するディレクトリはどこでも良いです。
ちなみにファイル名がそのままコマンド名になります。

1
$ vim $HOME/command/testcommand
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

if [[ $1 = "" ]]; then # 引数がない場合
echo "Error : Requires an argument" 1>&2
exit 2
elif [[ $# -gt 1 ]]; then # 引数が複数の場合
echo "Error : Too many arguments" 1>&2
exit 2
else
echo $1
fi

このままではコマンドを実行できないので、$HOME/commandにPATHを通します。
.bash_profileに以下を記述します。

1
$ vim ~/.bash_profile
1
export PATH=$HOME/command:$PATH

続いて、以下を実行します。

1
source ~/.bash_profile

PATHが通ったので、作成したコマンドtestcommandを以下の3パターンで実行します。

  1. 引数なし
  2. 引数が複数
  3. 引数が1つ
1
2
3
4
5
6
7
8
9
10
11
# 1. 引数なし
$ testcommand
Error : Requires an argument

# 2. 引数が複数
$ testcommand test1 test2
Error : Too many arguments

# 3. 引数が1つ
$ testcommand test
test

期待通りの結果が得られました。
が、これは以下を実行しているのと特に変わりないですね。

1
2
3
$ sh testcommand
$ sh testcommand test1 test2
$ sh testcommand test

次はオプション付きのコマンドを作成します。

オプション付きのコマンドを作成

続いて以下のようなシンプルなオプション付きのコマンドを作成します。

  • コマンド名を標準出力させる
  • -aの場合はdateコマンドを実行する
  • -bの場合は引数を標準出力させる
  • -h、もしくは存在しないオプションの場合はコマンドの使用方法を標準出力させる

先ほどのtestcommandを以下のように書き換え、オプションを処理できるようにします。

1
$ vim $HOME/command/testcommand
testcommand
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash

function usage {
cat <<EOM
# コマンドの使用方法を記述する
Usage: $(basename "$0") [OPTION]...
-h Display help
-a Display date
-b VALUE Display argument
EOM

exit 2
}

function function_a() {
date
}

function function_b() {
echo ${OPTARG}
}

# 各オプションに応じた実行内容を記述する
while getopts ":ab:h" optKey; do
case "$optKey" in
a)
# -aの場合の実行内容
function_a
;;
b)
# -bの場合の実行内容
function_b
;;
'-h'|'--help'|* )
# -h、--helpの場合、もしくは-a、-b以外の場合の実行内容
usage
;;
esac
done

# オプションの有無にかかわらず以下が実行される
echo "this command is $(basename ${0})"

getoptsコマンドの引数、":ab:h"の部分について補足します。

用意したオプションについて、引数が必要なものはうしろに:をつけてすべてのオプションを並べます。
先頭の:は、存在しないオプションが実行された際のエラーメッセージを非表示にすることができます。

では、作成したコマンドを以下の6パターンで実行します。

  1. オプションなし
  2. オプション-aのみ
  3. オプション-bのみ
  4. オプション-a-b
  5. オプション-h
  6. オプション-c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 1. オプションなし
$ testcommand
this command is testcommand

# 2. オプション-aのみ
$ testcommand -a
Mon Apr 5 01:26:38 2021
this command is testcommand

# 3. オプション-bのみ
$ testcommand -b argument_b
argument_b
this command is testcommand

# 4. オプション-aと-b
$ testcommand -a -b argument_b
Mon Apr 5 01:26:51 2021
argument_b
this command is testcommand

# 5. オプション-h
$ testcommand -h
Usage: testcommand [OPTION]...
-h Display help
-a Display date
-b VALUE Display argument

# 6. オプション-c
$ testcommand -c
Usage: testcommand [OPTION]...
-h Display help
-a Display date
-b VALUE Display argument

オプション付きコマンドの場合も期待通りの結果が得られました。

さいごに

今回作成したコマンドはまったく実用性がありませんが、便利なコマンドを思いついた方はぜひ作成してみてはいかがでしょうか。

シェルスクリプト連載の6日目でした。明日は岸本卓也さんのBashのシェル展開についてです。