私のローカルコンピュータにmicrok8s(Micro Kubernetes)をインストールした後に私が出会ったコマンドの1つmicrok8s.enable dns
はmicrok8s enable dns
。git status
有効なコマンドですが、git.status
そうではありません。 Linuxシステムはこのタイプのコマンド構造をどのようにサポートしますか?この動作をBashスクリプトにどのように統合できますか?
答え1
時には、プログラム(およびスクリプト)がプログラムを呼び出すために使用されたファイル名を確認し、そのファイルに基づいて動作を決定することがあります。
たとえば、次のファイルとシンボリックリンクを考えてみましょう。
$ 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)
て比較できます。 1つはもう1つへのリンクですか?そうでなければ、inode番号は同じですか?
答え2
これは、使用された「サブコマンド」に従って複数のタスクを実行するためのツールを提供する非常に一般的な方法になりました。私が知っている限り、どのようにも標準化されておらず、基本的なコマンド名とサブコマンドを一緒に書くときにドットを区切り文字として使用することは、これらのツールでは確かに一般的ではありません。
一部のツールはサブコマンドを介してのみ呼び出すことができますgit
(たとえば、git
単独で呼び出す場合は独自のヘルプテキストを提供します)。手動同様のサブコマンドの場合man command-subcommand
(サブコマンドの場合git
)
あなたは明らかにcommand-subcommand
呼び出すことができるツールを見つけました(しかしドットがあります)。またはのようにcommand subcommand
。この場合、基本コマンドと組み合わせた各コマンドは、同じファイルへのシンボリックリンクまたはハードリンクであることがわかります。
プログラム(スクリプトでもコンパイルされたバイナリでも)は、名前と引数を呼び出して簡単にチェックし、それに応じて動作を調整できます。
process
以下は、上のようにサブコマンドを最初の引数として使用したり、上のようにサブコマンドprocess action
として呼び出すことができる仮想コマンドの例ですprocess-action
。
このスクリプトによって実装されたサブコマンドは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
POSIXのためにこの記事を書いた理由は、sh
作業に難解なものが必要ないからです。bash
ACプログラムは、他のコンパイルまたは解釈言語で書かれたプログラムと同様の方法で操作を実行します。これには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"