it-swarm-ko.tech

echo가 쉘 내장 명령 인 이유는 무엇입니까?

$ which echo
echo: Shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat

Echo가 ls, ps, cat 등과 같은 독립 유틸리티가 아닌 이유는 무엇입니까? 왜 쉘에만 국한됩니까? 좋은 이유가 있습니까?

35
Lazer

내장 기능에는 두 가지 클래스가 있습니다.

  1. 일부 명령은 외부에있는 경우 작동 할 수 없기 때문에 셸 프로그램 자체에 내장되어야합니다.

    cd은 외부인 경우 자체 디렉토리 만 변경할 수 있기 때문에 하나입니다. 셸의 현재 작업 디렉터리에는 영향을주지 않습니다. (참조 : cd이 프로그램이 아닌가? )

  2. 다른 클래스의 명령은 순전히 효율성을 위해 셸에 내장되어 있습니다.

    dashman page 에는이 클래스에있는 명령의 예로 printf, echotest을 언급하는 내장 섹션이 있습니다.

Unix 시스템에는 항상 두 번째 클래스의 명령에 대해 별도의 실행 파일이 포함되어 있습니다. 이러한 별도의 실행 파일은 내가 사용한 모든 Unixy 시스템에서 여전히 사용할 수 있습니다. 물론 사용할 가능성이있는 모든 셸에도 내장되어 있습니다. ( POSIX 실제로 이러한 실행 파일이 있어야합니다.)

나는 echo이 AT & T Unix System V Release 3.1의 쉘에 내장되었다고 믿습니다. 저는 AT & T B1 시리즈 Unix 시스템 에 대한 두 가지 다른 버전의 매뉴얼 비교를 기반으로합니다. 누군가가 친절하게이 매뉴얼의 1986 년판을 스캔하고 온라인으로 올려 ; 이는 SVR3의 원래 릴리스에 해당합니다. echo UNIX System V 사용 설명서, 볼륨 II 의 523 페이지 목록에없는 것을 볼 수 있습니다. 명령이 셸에 내장 된 경우 예상 할 수 있습니다. 1987 년 SVR3.1 매뉴얼의 로컬 문서 사본에서 echo 매뉴얼의이 섹션에 나열되어 있습니다.

나는 이것이 Berkeley가 아니라고 확신합니다 . CSRG AT & T가 집으로 가져온 혁신입니다. 4.3BSD는 1986 년 SVR3와 같은 해에 나왔지만 4.3BSD의 sh.1 맨 페이지 를 보면 echo이 "특수 명령"섹션의 내장 명령 목록에 없음을 알 수 있습니다. . CSRG가 이렇게했다면이를 증명할 문서화 된 소스를 원하게됩니다.

이 시점에서 echo이 SVR3.1 이전의 셸에 빌드되었는지 그리고이 사실이 그때까지 단순히 문서화되지 않았는지 궁금 할 수 있습니다. 제가 사용할 수있는 최신 SVR3 이전 AT & T Unix 소스 코드는 PDP-11 System III tarball 에 있습니다. 여기서 Bourne Shell 소스 코드를 찾을 수 있습니다. /usr/src/cmd/sh/msg.c에있는 내장 명령 테이블에서 echo을 찾을 수 없습니다. 해당 파일의 타임 스탬프를 기반으로하면 echo이 1980 년에 셸에 없었 음을 확실히 알 수 있습니다.


하찮은 일

동일한 디렉토리에는이 질문에 대한 정확한 내용이 포함되지 않은 builtin.c라는 파일도 포함되어 있지만 다음과 같은 흥미로운 주석이 있습니다.

/*      
    builtin commands are those that Bourne did not intend
    to be part of his Shell.
    Redirection of i/o, or rather the lack of it, is still a
    problem..
*/      
72
Warren Young

일부 명령이 내장 된 세 번째 이유는 외부 명령을 실행할 수 없을 때 사용할 수 있습니다.

때때로 시스템이 너무 손상되어 ls 명령이 작동하지 않습니다. 어떤 경우에는 echo *가 계속 작동합니다.

또 다른 (더 중요한!) 예는 kill입니다. 시스템에 사용 가능한 PID가 부족하면 /bin/kill를 실행할 수 없습니다 (PID가 필요하기 때문에 :-). kill에서 작동합니다.

Btw., which은 외부 명령 (적어도 bash에서는 내부 명령이 아님)이므로 내부 명령을 나열 할 수 없습니다. 예를 들면 :

$ which echo
/bin/echo
$ type -a echo
echo is a Shell builtin
echo is /bin/echo
19
bhm

Bash Reference Manual 에 따르면 편의성에 관한 것입니다.

쉘은 또한 별도의 유틸리티를 통해 얻을 수 없거나 불편한 기능을 구현하는 작은 내장 명령 (내장) 세트를 제공합니다. 예를 들어 cd, break, continue 및 exec)는 셸 자체를 직접 조작하기 때문에 셸 외부에서 구현할 수 없습니다. 히스토리, getopts, kill 또는 pwd 내장 기능은 다른 것 중에서도 별도의 유틸리티로 구현할 수 있지만 내장 명령으로 사용하는 것이 더 편리합니다. 모든 셸 내장 기능은 이후 섹션에서 설명합니다.

Advanced Bash Scripting Guide 에 더 자세한 설명이 있습니다.

"내장은 문자 그대로 내장 된 Bash 도구 세트에 포함 된 명령입니다. 이는 성능상의 이유로 내장 기능이 외부 명령보다 빠르게 실행되며 일반적으로 분기를 필요로하는 별도의 프로세스 1 또는 특정 내장 기능이 셸 내부에 직접 액세스해야하기 때문입니다. "

또한 echo은 일부 시스템에서 독립 실행 형 유틸리티로 존재합니다. 내 Darwin 시스템 (MacOSX 10.5.8-Leopard)에있는 내용은 다음과 같습니다.

$ uname -a
Darwin Host.foo.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
$ bash --version
GNU bash, version 3.2.17(1)-release (i386-Apple-darwin9.0)
Copyright (C) 2005 Free Software Foundation, Inc.
$ which echo
/bin/echo

echo도 내장되어 있지만 내 스크립트는 내 Mac에서/bin/echo를 사용하고 대부분의 Linux 및 FreeBSD 시스템에서 Bash 내장을 사용합니다. 그러나 스크립트가 모든 곳에서 여전히 잘 작동하기 때문에 그것은 중요하지 않은 것 같습니다.

13
Stefan Lasiewski

Bhm의 대답을 보완하기 위해 /bin이 (가) 실수로 PATH에서 삭제되었습니다. 당신은 echo $PATH 그것을 알아 내기 위해서 죠?

6
Daniel Hershcovich

오늘날 대부분의 셸에는 내장 echo이 포함되어 있지만 GNU CoreUtils에는 독립 실행 형 구현도 포함되어 있습니다.

$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo

GNU Coreutils가 설치되어 있지 않은 것 같습니다 (대부분의 Linux 기반 데스크톱 및 서버 OS에는 기본적으로 설치되어 있지만 포함 된 Linux 또는 기타 UNIX는 대신 Shell 유틸리티의 대체 컬렉션을 사용할 수 있음)) .

BTW : Busybox 를 보면 ls, pscat도 거기에 내장 된 명령 (또는 최소한 가능합니다. 임베디드 시스템에 사용되며 필요하지 않은 모든 것은 생략 할 수 있습니다.).

2
JanC

다음은 echo이 쉘 내장이어야하는 실제 이유입니다.

$PASSWORD에 비밀번호가 있다고 가정합니다. ./password 파일에 어떻게 쓰나요? 당연히 대부분의 프로그래머는 다음과 같이 작성할 것입니다.

echo "$PASSWORD" >./password

그러나 echo가 Shell 내장이 아닌 경우 ps 정보를 통해 모든 사용자에게 암호가 유출됩니다.

물론 현명하게 알고 싶다면 echo없이 암호를 저장하는 방법을 찾을 수 있습니다. 다른 쉘 기능을 이용할 수도 있습니다.

cat >./password <<EOF
${PASSWORD}
EOF

그러나 echo를 내장 파일로 사용하는 것은 암호를 파일에 저장하는 가장 확실한 방법도 작동해야하기 때문에 중요한 안전 벨트입니다.

1
DepressedDaniel