쉘 내장 명령 이해


12

에서에서 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실제로 쉘의 일부가 아닌 경우 별도의 명령이 어떻게 될 수 있습니까?


1
일부 명령은 원래 별도의 유틸리티로 존재했습니다. 현재 POSIX 표준 준수, 이식성 및 이전 버전과의 호환성이 있습니다. 쉘은 성능을 위해 내장 된 것을 구현합니다. 다른 이유가있을 수 있지만, 너무 자세하게 설명하지 않아도됩니다.
Sergiy Kolodyazhnyy

1
내가 생각할 수있는 또 다른 이유는 exec파일 설명자를 조작하고 eval 명령을 평가하는 것과 같이 쉘에 특별히 내장 명령이 필요하기 때문 입니다. 그들은 독립형 명령으로 필요하지 않습니다
Sergiy Kolodyazhnyy

답변:


16

쉘에 내장 된 명령은 종종 성능 향상으로 인해 내장됩니다. 예를 들어 외부 호출은 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이론 상으로는 그렇게 할 수는 없지만 (그다지 많이하지는 않을 것이라고 가정합니다).


IIRC가, chdir/ cd초기 유닉스 외부 바이너리했다 / 사전 유닉스 전에 fork도입되었다.
Xophmeister

@Xophmeister Solaris 11.4 (베타)에는 여전히가 /usr/bin/cd있지만 현재 작업 디렉토리를 실제로 변경하지는 않습니다. 매뉴얼은 : /usr/bin/cd호출 프로세스에 영향을 미치지 않지만 주어진 디렉토리를 현재 디렉토리로 설정할 수 있는지 여부를 결정하는 데 사용할 수 있습니다.
Kusalananda

2
내장에 대한 또 다른 구체적인 이유 : 내장 kill은 다른 프로세스를 포크 할 필요가 없기 때문에 좋습니다. 프로세스 수 제한에 도달하면 좋습니다.
derobert

7

당신은 (매우 당연하게도) 일부 내장 명령이 존재한다는 사실에 의해 혼동 모두 내장 명령으로 하고 외부 명령한다. 예를 들어 /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

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


왜 distro. 이미 존재하는 내부 명령에 대해 별도의 외부 명령을 제공합니까? 왜 복제합니까?
LoveWithMaths

1
@linuxuser 이러한 유틸리티 중 일부는 POSIX에 필요하며 사용자가 사용하는 쉘이 내장 기능을 제공하는지 알 수 없습니다. 그것들을 OS의 내부 명령으로 생각하지 말고 쉘의 내부 명령 일뿐이며 쉘은 변경 될 수 있습니다.
terdon

내부 명령이 쉘에 의해 제공된다면 지금 의심의 여지가 있습니다. 그렇다면 누가 외부 명령을 제공합니까? 내부 명령과 외부 명령으로 사용 가능한 많은 명령을 관찰했지만 명시 적으로 설치하지 않았습니다. 그래서 누가 외부 명령을 제공합니까? Distro는 정확한 정보를 제공합니까?
LoveWithMaths

@linuxuser는 명령 및 운영 체제에 따라 다릅니다. 예를 들어, 내 아치 리눅스 /bin/printf에서 coreutils패키지와 /bin/kill로 설치 됩니다 util-linux.
terdon

죄송하지만 아직 확실하지 않습니다. 위 중 어느 것이 distro에 의해 제공됩니까? 그리고 배포판에서 제공하지 않은 다른 사람은 무엇을 제공합니까?
LoveWithMaths
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.