내 로컬 컴퓨터에 microk8s(Micro Kubernetes)를 설치한 후 내가 만난 명령 중 하나 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)
하고 비교할 수 있습니다. 하나는 다른 하나에 대한 링크입니까? 그렇지 않다면 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
스크립트와 함께 각 하위 명령에 하나씩 일련의 하드 또는 기호 링크가 있습니다. 여기서는 하드 링크를 생성하도록 선택합니다.
$ 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"