[unix] 쉘 내장 명령 이해

에서에서 bash는 설명서 , 그것은 것을 쓰여

Builtin commands are contained >>> within <<< the shell itself

또한 답변은

A built-in command is simply a command that the shell carries out itself,
instead of interpreting it as a request to load and run some
>>> other program <<<

내가 실행하는 경우 compgen -bbash 4.4, 나는 명령 내장 모든 쉘의 목록이 표시됩니다. 그 예를 들어, 참조 [kill쉘 내장 명령으로 나열되어 있습니다. 그러나 실제 위치는 다음과 같습니다.

/usr/bin/[
/bin/kill

나는 builtin명령이 /bin/bash실행 파일 로 컴파일 되는 것을 의미 한다고 생각했습니다 . 그래서 정말로 혼란 스럽습니다 : 저를 수정하십시오. 그러나 builtin실제로 쉘의 일부가 아닌 경우 별도의 명령이 어떻게 될 수 있습니까?



답변

쉘에 내장 된 명령은 종종 성능 향상으로 인해 내장됩니다. 예를 들어 외부 호출은 printf내장 기능을 사용하는 것보다 느립니다 printf.

일부 유틸리티는 내장되어있을 필요 가 없으므로 특별한 경우가 아니라면 외부 유틸리티 cd로도 제공됩니다 . 이것은 스크립트가 내장 된 스크립트를 제공하지 않는 쉘에 의해 해석되는 경우 스크립트가 중단되지 않도록하기위한 것입니다.

일부 쉘의 내장 기능은 외부 동등한 명령에 대한 확장도 제공합니다. printf예를 들어 Bash 는

$ printf -v message 'Hello %s' "world"
$ echo "$message"
Hello world

외부 /usr/bin/printf변수는 현재 쉘 세션에서 쉘 변수에 액세스 할 수 없으므로 변경할 수 없습니다 (변수로 인쇄).

내장 유틸리티에는 확장 된 명령 행이 특정 길이보다 짧아야한다는 제한 이 없습니다 . 하기

printf '%s\n' *

따라서 printf쉘 내장 명령 인 경우 안전합니다 . 명령 행 길이 제한 execve()은 외부 명령을 실행하는 데 사용되는 C 라이브러리 기능 에서 비롯됩니다 . 명령 행과 현재 환경이 ARG_MAX바이트 보다 큰 경우 ( getconf ARG_MAX쉘 참조 ) 호출 execve()이 실패합니다. 유틸리티가 쉘에 내장되어 execve()있으면 호출 할 필요가 없습니다.

내장 유틸리티는에있는 유틸리티보다 우선 $PATH합니다. 내장 명령 해제하려면 bash, 사용 예를

enable -n printf

쉘에 내장 해야하는 간단한 유틸리티 목록이 있습니다 (POSIX 표준의 특수 내장 목록에서 가져옴 ).

break
colon (:)
continue
dot (.)
eval
exec
exit
export
readonly
return
set
shift
times
trap
unset

이들은 현재 쉘 세션의 환경과 프로그램 흐름을 직접 조작하기 때문에 내장되어야합니다. 외부 유틸리티는 그렇게 할 수 없습니다.

흥미롭게 cd도이 목록의 일부는 아니지만 POSIX 는 이에 대해 다음과 같이 말합니다 .

cd현재 쉘 실행 환경에 영향을주기 때문에 항상 쉘 일반 내장으로 제공됩니다. 서브 쉘 또는 별도의 유틸리티 실행 환경에서 호출되는 경우 (예 : 다음 중 하나) :

(cd /tmp)
nohup cd
find . -exec cd {} \;

호출자 환경의 작업 디렉토리에는 영향을 미치지 않습니다.

그러므로 나는 “특별한”빌트인은 외부 대응 물을 가질 수 없지만 cd이론 상으로는 그렇게 할 수는 없지만 (그다지 많이하지는 않을 것이라고 가정합니다).


답변

당신은 (매우 당연하게도) 일부 내장 명령이 존재한다는 사실에 의해 혼동 모두 내장 명령으로 하고 외부 명령한다. 예를 들어 /bin/[명령이 있다는 것이 맞지만 “실제 위치”가에 있다는 것을 의미하지는 않습니다 /bin.

이것을 테스트하는 쉬운 방법은 사용 가능한 모든 명령 인스턴스를 표시 type하는 -a스위치 로 실행 하는 것입니다. 내 아치 시스템에서 다음을 보여줍니다.

$ type -a [
[ is a shell builtin
[ is /sbin/[
[ is /usr/sbin/[
[ is /usr/bin/[

그 주 /sbin, /usr/sbin그리고 /bin가리키는 모든 심볼릭 링크되어 /usr/bin있으므로 단지 외부의 하나가, [:

$ readlink -f /usr/sbin /sbin /bin/
/usr/bin
/usr/bin
/usr/bin

보시다시피 [, 내장 명령과 외부 명령 모두이며, 다른 다양한 쉘 내장에서도 마찬가지입니다. 그러나 이것도 쉘 자체로 컴파일 된 쉘 내장이라는 사실을 변경하지는 않습니다.


답변