ローカルマシンにmicrok8s(Micro Kubernetes)をインストールした後、遭遇したコマンドの1つはmicrok8s.enable dns
で、microk8s enable dns
としても実行できます。これは普遍的なものではないようです。 git status
は有効なコマンドですが、git.status
は無効です。 Linuxシステムはこのようなタイプのコマンド構造をどのようにサポートしますか?この動作をBashスクリプトに組み込むにはどうすればよいですか?
プログラム(およびスクリプト)が、プログラムの呼び出しに使用されたファイルの名前を検査し、その動作を条件付けするのを見かけることがあります。
たとえば、次のファイルとシンボルリンクを考えてみます。
_$ ls -l
-rwxr-xr-x ... foo
lrwxr-xr-x ... foo.bar -> foo
_
そして、スクリプトの内容foo
:
_#!/bin/bash
readonly command="$(basename "${0}")"
subcommand="$(echo "${command}" | cut -s -d. -f2)"
if [[ "${subcommand}" == "" ]]; then
subcommand="${1}"
fi
if [[ "${subcommand}" == "" ]]; then
echo "Error: subcommand not specified" 1>&2
exit 1
fi
echo "Running ${subcommand}"
_
スクリプトはコマンド名を解析し、(質問のドット表記に基づいて)サブコマンドを探します。これで、_./foo.bar
_を実行して、_./foo bar
_を実行するのと同じ動作を得ることができます。
_$ ./foo.bar
Running bar
$ ./foo bar
Running bar
_
明確にするために、それが_microk8s.enable
_が行っていることを知りません。 ls -li $(which microk8s.enable) $(which microk8s)
を実行して、ファイルを比較できます。一方は他方へのリンクですか?そうでない場合、それらは同じiノード番号を持っていますか?
これは、使用されている「サブコマンド」に応じて複数のアクションを実行できるツールを提供するかなり一般的な方法になっています。私が知っている方法では標準化されておらず、ベースコマンド名とサブコマンドを一緒に書き込むときに、それらをドットとしてセパレーターとして使用することは、これらのツールに一般的ではありません。
一部のツールはgit
(git
自体が単独で呼び出されるとヘルプテキストを提供します)のように、サブコマンドでのみ呼び出すことができますが、manualsを提供しますman command-subcommand
のようなサブコマンド(git
サブコマンドの場合と同様)。
command-subcommand
(ドットあり)orとしてcommand subcommand
と呼ばれるツールを見つけました。この場合、ベースコマンドと各結合コマンドの両方が、1つの同じファイルへのシンボリックリンクまたはハードリンクであることがわかります。
プログラム(スクリプトまたはコンパイル済みバイナリー)は、呼び出された名前と引数を使用して簡単に検査し、それに応じてアクションを調整できます。
以下は、process action
のようにサブコマンドを最初の引数として取るか、process-action
のようなサブコマンドで呼び出すことができる架空のprocess
コマンドの例です。
このスクリプトによって実装されるサブコマンドは、compile
、debug
、およびmogrify
です。
#!/bin/sh
basecmd=process # base command name
cmd=${0##*/} # get command name ( basename "$0" )
subcmd= # no sub command yet
# Now pick out the sub command from the command name,
# or from the first argument. Then fail if unsuccessful.
case $cmd in
"$basecmd"-*) # has sub command in command name
subcmd=${cmd#$basecmd-}
esac
if [ -z "$subcmd" ] && [ "$#" -ge 1 ]; then
# called as "process action"
# rather than as "process-action"
subcmd=$1
shift # remove sub command from argument list
fi
if [ -z "$subcmd" ]; then
echo 'No action' >&2
exit 1
fi
# Act on the sub command.
# Each action would probably be implemented as a function,
# possibly called as
# somefunction "$@"
# ... passing the remaining command line argument to it.
case $subcmd in
compile) # do "compile" action
echo 'compile'
;;
debug) # do "debug" action
echo 'debug'
;;
mogrify) # do "mogrify action"
echo 'mogrify'
;;
*)
printf 'Invalid action "%s"\n' "$subcmd" >&2
exit 1
esac
これを機能させるためにsh
を必要とする不思議なことは何もないので、私はPOSIX bash
のためにこれを書きました。 Cプログラムは、他のコンパイルまたは解釈された言語で書かれたプログラムと同様に、物事を行います。これにはLinuxも必要ありません。私はこれをOpenBSDで書いてテストしていますが、どのPOSIXシステムでも動作するはずです。
この基本process
スクリプトとともに、各サブコマンドに1つずつ、ハードリンクまたはシンボリックリンクのセットが作成されます。ここでは、ハードリンクを作成することにしました。
$ ls -li
total 8
244420 -rwxr-xr-x 4 kk wheel 538 May 9 21:55 process
244420 -rwxr-xr-x 4 kk wheel 538 May 9 21:55 process-compile
244420 -rwxr-xr-x 4 kk wheel 538 May 9 21:55 process-debug
244420 -rwxr-xr-x 4 kk wheel 538 May 9 21:55 process-mogrify
これらの名前はそれぞれ、同じスクリプトの別の名前にすぎません。
テスト実行:
$ ./process mogrify
mogrify
$ ./process-mogrify
mogrify
$ ./process
No action
$ ./process-compile
compile
$ ./process compile
compile
$ ./process compilee
Invalid action "compilee"