최근 동료가 "무엇입니까 man
? "라고 물었습니다. 이에 대해 알아보고 나면Bash CLI에서 액세스할 수 있는 모든 것이 명령은 아닙니다., 나는 조심스럽게 주문을 요청했습니다 man
.
man man
그냥 인터페이스라고 부르세요.
NAME
man - an interface to the on-line reference manuals
man
실행 파일이 있습니다:
$ which man
/usr/bin/man
$ file /usr/bin/man
/usr/bin/man: ELF 64-bit LSB shared object
man
실행 파일이 있는 프로그램도 마찬가지입니까? 다른 명사는 무엇입니까 man
? 그것을 가장 잘 설명하는 명사는 무엇입니까?사실 저는 일반적인 경우에 관심이 있어요나결정할 수 있는 것은 thing on the cli
임의적이며 man
이는 단지 예일 뿐입니다.
그렇다면 Bash CLI에서 사용할 수 있는 모든 것을 가리키는 단어는 무엇입니까? 명령, 별칭, 시스템 호출 등을 포함하는 단어는 무엇입니까?
답변1
POSIX 용어에서 셸에 작업을 요청하는 모든 것은명령:
특정 작업을 수행하도록 셸에 지시하는 지침입니다.
그래서
man man
(기술적으로) 명령입니다.
man
man
도유틸리티:
셸 명령 언어의 일부로 제공되는 특수 내장 유틸리티를 제외하고 특정 작업이나 관련 작업 집합을 수행하기 위해 셸에서 이름으로 호출할 수 있는 프로그램입니다.
(여기서 배제는 중요하지 않습니다.특정 속성을 가진 특수 내장 유틸리티.)
주어진 명령이 무엇인지 알아내려면 를 사용하십시오 type
. 그러면 그것이 내장된 명령인지, 프로그램인지 PATH
(어디인지), 별칭 등인지(또는 알 수 없는지) 알 수 있습니다.
시스템 호출은 쉘 명령으로 사용할 수 없습니다.
당신은 또한 볼 수 있습니다명령인가요 아니면 유틸리티인가요?그리고내장 명령과 비 내장 명령의 차이점은 무엇입니까?
답변2
맨 아래에서 시작:
시스템 호출
시스템 호출은 사용자 공간 작업이 커널에서 특정 서비스를 요청하고 권한 있는 커널 모드로 실행되는 방법입니다.
프로그래밍 언어가 C이고 작업에서 현재 디렉터리를 변경하려는 경우 다음을 삽입해야 합니다.chdir()프로그램에 지침을 추가하세요.
물론 이 프로그램들은즉시는 아님명령줄에서 액세스할 수 있습니다. vg 명령줄에 chdir을 입력해도 chdir 시스템 호출이 호출되지 않습니다.
사용 가능한 모든 시스템 호출 목록은 물론 커널에 따라 다르며 신뢰할 수 있는 유일한 소스는 물론 include/linux/syscalls.h
커널 소스 배포판의 헤더 파일입니다.
지시하다
CLI는 실행 중인 작업에 대한 인터페이스입니다. 당신이 입력하는 것은 무엇이든 호출됩니다지침단지 작업이 무언가를 성취하도록 지시하기로 되어 있기 때문입니다.
주문하다
입력한 내용은 먼저 인터프리터를 거쳐 입력한 토큰에 대한 어휘 분석을 수행하고 특정 쉘의 경우 이름을 인식할 수 있습니다.주문하다(변수 할당이 아닌 것으로 이해됨) 요청을 구현하려면 다른 프로그램을 사용해야 한다고 우연히 결정했습니다. 그런 다음 다른 프로그램의 바이너리를 실행할 하위 프로세스를 포크합니다.
그러나 일부 특수한 경우에는 외부 절차(예: 간단한 미적분)를 사용하지 않고 요청을 이행하는 것이 더 쉬울 수도 있습니다. 더 중요한 것은~ 해야 하다요청을 내부적으로 수행합니다.
내장 명령
Active Directory를 변경하려는 원래 의도로 돌아가서 사용자는 잘 알려진 셸 명령을 실행합니다 cd
. 사용자가 정말로 원하는 것은 쉘의 현재 디렉토리를 변경하는 것입니다. 그리고 chdir 시스템 호출은 호출자의 현재 작업 디렉토리만 변경하기 때문에 쉘은 상위 프로세스를 변경하지 않는 다른 프로세스를 포크할 수 없습니다. 쉘은 내부적으로 chdir 시스템 호출을 실행해야 합니다.
yourshellname
쉘 내장 명령은 모든 매뉴얼 페이지에 나열되어 있습니다.
별명
별명는 모든 사용자가 설정할 수 있는 동의어에 지나지 않으며 명령줄 해석기에 의해 원하는 문자열(셸에 대한 적법한 명령을 나타내야 함)로 변환됩니다.
alias
현재 활성화된 모든 별칭 목록은 쉘 내장 명령을 통해 얻을 수 있습니다.
답변3
명령을 식별하는 데 도움이 되는 작은 쉘 스크립트가 있습니다. 즉, 명령 유형이 무엇인지, 패키지를 통해 설치된 경우 해당 패키지는 무엇인지입니다. 아마도 이 이름으로 what-about
,
#!/bin/bash
LANG=C
inversvid="\0033[7m"
resetvid="\0033[0m"
if [ $# -ne 1 ]
then
echo "Usage: ${0##*/} <program-name>"
echo "Will try to find corresponding package"
echo "and tell what kind of program it is"
exit 1
fi
command="$1"
str=;for ((i=1;i<=$(tput cols);i++)) do str="-$str";done
tmp="$command"
first=true
curdir="$(pwd)"
tmq=$(which "$command")
tdr="${tmq%/*}"
tex="${tmq##*/}"
if test -d "$tdr"; then cd "$tdr"; fi
#echo "cwd='$(pwd)' ################# d"
while $first || [ "${tmp:0:1}" == "l" ]
do
first=false
tmp=${tmp##*\ }
tmq="$tmp"
tmp=$(ls -l "$(which "$tmp")" 2>/dev/null)
tdr="${tmq%/*}"
tex="${tmq##*/}"
if test -d "$tdr"; then cd "$tdr"; fi
# echo "cwd='$(pwd)' ################# d"
if [ "$tmp" == "" ]
then
tmp=$(ls -l "$tex" 2>/dev/null)
tmp=${tmp##*\ }
if [ "$tmp" == "" ]
then
echo "$command is not in PATH"
# package=$(bash -ic "$command -v 2>&1")
# echo "package=$package XXXXX 0"
bash -ic "alias '$command' > /dev/null 2>&1" > /dev/null 2>&1
if [ $? -ne 0 ]
then
echo 'looking for package ...'
package=$(bash -ic "$command -v 2>&1"| sed -e '0,/with:/d'| grep -v '^$')
else
echo 'alias, hence not looking for package'
fi
# echo "package=$package XXXXX 1"
if [ "$package" != "" ]
then
echo "$str"
echo "package: [to get command '$1']"
echo -e "${inversvid}${package}${resetvid}"
fi
else
echo "$tmp"
fi
else
echo "$tmp"
fi
done
tmp=${tmp##*\ }
if [ "$tmp" != "" ]
then
echo "$str"
program="$tex"
program="$(pwd)/$tex"
file "$program"
if [ "$program" == "/usr/bin/snap" ]
then
echo "$str"
echo "/usr/bin/snap run $command # run $command "
sprog=$(find /snap/"$command" -type f -iname "$command" \
-exec file {} \; 2>/dev/null | sort | tail -n1)
echo -e "${inversvid}file: $sprog$resetvid"
echo "/usr/bin/snap list $command # list $command"
slist="$(/usr/bin/snap list "$command")"
echo -e "${inversvid}$slist$resetvid"
else
package=$(dpkg -S "$program")
if [ "$package" == "" ]
then
package=$(dpkg -S "$tex" | grep -e " /bin/$tex$" -e " /sbin/$tex$")
if [ "$package" != "" ]
then
ls -l /bin /sbin
fi
fi
if [ "$package" != "" ]
then
echo "$str"
echo " package: /path/program [for command '$1']"
echo -e "${inversvid} $package ${resetvid}"
fi
fi
fi
echo "$str"
#alias=$(grep "alias $command=" "$HOME/.bashrc")
alias=$(bash -ic "alias '$command' 2>/dev/null"| grep "$command")
if [ "$alias" != "" ]
then
echo "$alias"
fi
type=$(type "$command" 2>/dev/null)
if [ "$type" != "" ]
then
echo "type: $type"
elif [ "$alias" == "" ]
then
echo "type: $command: not found"
fi
cd "$curdir"
echo
때로는 별도로 컴파일된 프로그램이자 쉘 내장 명령인 for 와 같은 두 가지 옵션이 있습니다 . 별도의 프로그램에 대한 전체 경로를 사용하지 않는 한, 내장된 쉘이 우선적으로 사용되며,
$ what-about echo
-rwxr-xr-x 1 root root 35000 jan 18 2018 /bin/echo
----------------------------------------------------------------------------------
/bin/echo: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=057373f1356c861e0ec5b52c72804c86c6842cd5, stripped
----------------------------------------------------------------------------------
package: /path/program [for command 'echo']
coreutils: /bin/echo
----------------------------------------------------------------------------------
type: echo is a shell builtin
rename
가끔 내가 사용한 버전 처럼 숨겨져 있을 수 있는 프로그램에 명령이 연결되어 있는 경우도 있습니다 .
$ what-about rename
lrwxrwxrwx 1 root root 24 maj 12 2018 /usr/bin/rename -> /etc/alternatives/rename
lrwxrwxrwx 1 root root 20 maj 12 2018 /etc/alternatives/rename -> /usr/bin/file-rename
-rwxr-xr-x 1 root root 3085 feb 20 2018 /usr/bin/file-rename
----------------------------------------------------------------------------------
/usr/bin/file-rename: Perl script text executable
----------------------------------------------------------------------------------
package: /path/program [for command 'rename']
rename: /usr/bin/file-rename
----------------------------------------------------------------------------------
type: rename is /usr/bin/rename
오류를 방지하기 위해 별칭이 있으며 rm
별칭이 에 우선합니다 PATH
. 백슬래시를 접두사로 사용하여 \rm
별칭을 건너뛰고 프로그램을 직접 실행할 수 있습니다. (별칭은 특정 사용자에게만 적용되며 sudo
유사한 별칭이 정의되어 있지 않은 한 다른 사용자에게는 적용되지 않는다는 점을 기억하십시오.)
$ what-about rm
-rwxr-xr-x 1 root root 63704 jan 18 2018 /bin/rm
---------------------------------------------------------------------------
/bin/rm: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for
GNU/Linux 3.2.0, uildID[sha1]=864c9bbef111ce358b3452cf7ea457d292ba93f0,
stripped
---------------------------------------------------------------------------
package: /path/program [for command 'rm']
coreutils: /bin/rm
---------------------------------------------------------------------------
alias rm='rm -i'
type: rm is /bin/rm