“ls”가 실행을 위해 별도의 프로세스가 필요한 이유는 무엇입니까?


14

ls실행을 위해 별도의 프로세스 가 필요한 이유는 무엇 입니까? cd포크 메커니즘으로 같은 명령을 실행할 수없는 이유를 알고 있지만 ls포크없이 실행 하면 해 가 있습니까?


1
하지만 ls외부 프로그램입니다 echo *또는 echo * .*(쉘 옵션에 따라) 분기하지 않고 파일을리스트 꽤 좋은 작업을 수행합니다.
gerrit

printf "% s \ n"*
Costa

쉘 다양성 참고 사항 : tcsh에는 다음 ls-F과 같은 기능 이 내장 되어 ls -F있습니다. 효율성을 위해 존재합니다. 항상 -F좋은 아이디어를 얻습니다 . 다른 옵션을 지정하면 외부 명령에 영향을줍니다.

답변:


18

대답은 ls외부 실행 파일입니다. 를 실행하여 위치를 확인할 수 있습니다 type -p ls.

ls그렇다면 왜 쉘에 내장되어 있지 않습니까? 왜 그래야합니까? 쉘의 역할은 사용 가능한 모든 명령을 포함하는 것이 아니라 실행할 수있는 환경을 제공하는 것입니다. 일부 현대 쉘이 echo, printf그리고하지 않는 내장 매크로, 그들의 동류 기술적으로 내장 명령해야하지만, 그들은 (주로 꽉 루프에서)를 반복해서 실행 성능 향상을 위해 이렇게 만들어집니다. 그것들을 내장하지 않으면, 쉘은 호출 할 때마다 새로운 프로세스를 분기시키고 실행해야하는데 이는 매우 느릴 수 있습니다.

최소한 ls외부 실행 파일을 실행하려면 exec 시스템 호출 제품군 중 하나를 실행해야합니다. 당신은 분기없이이 작업을 수행하지만, 당신이 사용하는 것을 기본 쉘을 대체 할 것이다. 다음을 수행하여 해당 인스턴스에서 어떤 일이 발생하는지 확인할 수 있습니다.

exec ls; echo "this never gets printed"

쉘의 프로세스 이미지가 교체되었으므로 현재 쉘에 더 이상 액세스 할 수 없습니다. ls를 실행 한 후 쉘을 계속 실행할 수 있으려면 명령을 쉘에 빌드해야합니다.

포킹은 기본 쉘이 아닌 프로세스를 대체 할 수있게하므로 나중에 쉘을 계속 실행할 수 있습니다.


1
나는 ls (1)이 쉘의 내장 기능이 아닌 이유를 묻고 있다고 생각합니다. 누군가가 다른 벤더가 ls (1)에 대해 다른 옵션을 가지고 파일 시스템과 다른 것들을 쿼리 할 수 ​​있는지 설명해야합니다. 포탄을 '내장'시키는 데 따른 기복.
llua

@llua 나는 그것에 대해 몇 가지 정보, 그리고 예외의 경우 추가 echo, printf
크리스 아래

왜 어떤 것이 내장되어 있고 다른 것이 왜 그렇지 않은지는 분명하지 않습니다. 예를 들어 왜 cd외부 실행 파일이 아닌가?
Faheem Mitha

@FaheemMitha이 있습니다 외부 cdPOSIX 호환 운영 체제에서 실행 파일 ( 여기 참조 ). 그러나 현재 프로세스에서 실제로 chdir ()을 수행하려면 쉘에 내장해야합니다.
Chris Down

ls외부적인 이유 는 습관 이되었지만 쉘로도 구현할 수 있습니다. busybox를 참조하십시오.

15

강타 참조 설명서 상태 :

내장 된 명령은 별도의 유틸리티로는 얻을 수 없거나 불편한 기능을 구현하는 데 필요합니다.

즉, 쉘은 다음과 같은 경우 내장 명령 포함 하도록 설계되었습니다 .

  1. POSIX 표준에 필요
  2. 작업 제어 내장과 같이 쉘 자체에 액세스해야하는 명령
  3. OS에 의존하지 않고 매우 간단한 명령으로 printf와 같은 내장 기능으로 구현할 때 실행 효율성이 향상됩니다.

ls명령은 위의 요구 사항에 맞지 않습니다.

그러나 여기 ls에는 bash 인터프리터와 동일한 프로세스에서 실행되는 내장 기능으로 구현되는 것을 막는 프로그래밍 제약이 없습니다 . 쉘 내장으로 명령이 실행 되지 않는 설계 이유 는 다음과 같습니다.

  1. 셸은 파일 시스템과 분리되어야합니다. 내장 명령은 파일 시스템 또는 주변 장치의 올바른 작동에 의존해서는 안됩니다
  2. 파일 시스템 유형이거나 OS에 따라 다를 수있는 명령은 별도의 실행 파일이어야합니다
  3. 파이프 또는 파이프하려는 명령은 별도의 프로세스 여야합니다.
  4. 백그라운드에서 실행하려는 명령은 별도의 실행 파일이어야합니다.
  5. 가능한 많은 매개 변수를 가진 명령은 별도의 실행 파일에서 더 잘 구현됩니다.
  6. 어떤 유형의 쉘 (bash, csh, tsh, ...)이 호출하는지에 관계없이 동일한 출력을 가져야하는 명령은 독립 실행 파일이어야합니다.

첫 번째 이유와 관련하여-쉘이 가능한 한 독립적이고 탄력적이기를 원합니다. 쉘 ls이 "아직 시도하지 않고 응답하지 않는"NFS 마운트에 걸리는 것을 원하지 않습니다.

두 번째 이유와 관련하여-많은 경우 Busybox를 사용하는 시스템 또는 다른 ls구현 을 가진 다른 파일 시스템에 쉘을 사용할 수 있습니다 . 또는 ls구현 이 다른 OS에서 동일한 셸 소스를 사용하십시오 .

세 번째 이유와 관련하여- 쉘 인터프리터와 동일한 프로세스에서 find . -type d | xargs ls -lad구현하기가 어렵거나 불가능한 표현식 ls입니다.

네 번째 이유와 관련하여-일부 ls명령을 완료하는 데 시간이 오래 걸릴 수 있습니다. 그 동안 쉘이 계속해서 다른 작업을 수행하기를 원할 수 있습니다.


참고 : 비슷한 질문에 대한 답변으로 Warren Young 의이 유용한 게시물 을 참조하십시오 .


별도의 명령이 있으면 파이프 출력의 용이성과 쉘 프리미티브를 별도의 실행 파일로 파이프하는 데 필요한 모든 프로그래밍을 놓쳤습니다.
Bruce Ediger

@BruceEdiger : 존경받는 BE로부터 의견을받는 것이 얼마나 기쁩니다. 감사! 나는 이유 3이 당신의 의견을 포함한다고 생각합니다.
Jonathan Ben-Avraham

1
외부 프로세스를 위해 파이프를 처리하고 가상 명령과 같은 내부 명령의 출력을 외부 프로세스로 파이프 해야하는 경우 쉘 자체의 소스 코드가 얼마나 복잡한 지에 대해 더 많이 생각하고있었습니다 ls. 가능하지만 복잡 할 것입니다.
Bruce Ediger

1
당신의 5 가지 포인트가 모두 헛소리가 아니라면 가장 두렵습니다. 1 : ls는 파일 시스템 구현과 독립적입니다. 표준 라이브러리 및 응용 프로그램에 일관된 인터페이스를 제공하는 것은 커널에 달려 있습니다. 2 : ls는 쉘보다 OS에 덜 의존적입니다. 3 : 쉘은 파이프 라인에 내장을 허용합니다. 4 : 쉘은 확실히 내장을 백그라운드에서 실행할 수있게합니다. 5 : 그것은 매우 주관적입니다.
jlliagre

1
@ JonathanBen-Avraham @BruceEdiger 쉘은 이미 서브 쉘이있는 내장의 파이프 케이스를 처리하지 않습니까? 예를 들어 bash출력 alias | grep ls. 입력cat /etc/passwd | while read a; do echo "$a"; done
Matt

2

ls별도의 프로세스가 필요하지 않습니다. 실제로 별도의 프로세스가 필요한 명령은 거의 없습니다. 권한을 변경해야하는 명령 만 있습니다.

일반적으로 쉘은 명령을 내장으로 구현해야하는 경우에만 명령을 내장으로 구현합니다. 명령과 같은 alias, cd, exit, export, jobs, ... 그러므로 읽거나 껍질의 일부 내부 상태를 수정하고 할 필요가 별도의 프로그램이 될 수 없습니다. 이러한 요구 사항이없는 명령은 별도의 명령 일 수 있습니다. 이런 식으로 어떤 쉘이나 다른 프로그램에서 호출 할 수 있습니다.

bash의 내장 목록을 보면 다음 내장 만 별도의 명령으로 구현할 수 있습니다. 이들 중 일부의 경우 기능이 약간 손실 될 수 있습니다.

  • command— 그러나 PATH제대로 설정되지 않고 스크립트 command를 설정하는 데 사용하는 상황에서는 유용성이 떨어 집니다.
  • echo — 효율성을위한 내장 기능입니다.
  • help — 별도의 데이터베이스를 사용할 수 있지만 셸 실행 파일에 도움말 텍스트를 포함하면 셸 실행 파일을 독립적으로 만들 수 있다는 이점이 있습니다.
  • kill — 기본 제공 기능에는 두 가지 장점이 있습니다. 프로세스 ID 외에도 작업 지정을 인식 할 수 있으며 별도의 프로세스를 시작할 수있는 리소스가 충분하지 않은 경우에도 사용할 수 있습니다.
  • printf—와 같은 이유로 echo그리고 -v출력을 변수에 넣는 옵션을 지원합니다 .
  • pwd — 기본 제공 기능은 논리적 현재 디렉토리 추적 기능을 추가로 제공합니다 (기호 링크를 확장하지 않고 그대로 유지).
  • test— 효율성을 위해 기본 제공되며 bash는 /dev/fd/…일부 운영 체제에서 호출 되는 파일로 마술을 수행합니다 .

몇몇 껍질은 상당수의 추가 내장을 제공합니다. 거기에 긴급 수리 독립형 바이너리 (때 일부 외부 명령을 사용할 수 없습니다) 할 수 있도록 설계 쉘입니다. ls라는 내장 -ls도구와 -grep및 같은 다른 도구가 -tar있습니다. 새시의 내장 기능은 본격적인 명령보다 기능이 적습니다. Zsh는 zsh / files 모듈 에 유사한 내장 기능을 제공 합니다 . 에는 ls없지만 와일드 카드 확장 ( echo *)이 있으며 zstat비슷한 기능을 수행 할 수 있습니다.


2

사람들이 여기서 놓친 것은 lsLinux 에서 GNU 프로그램의 복잡성 때문이라고 생각합니다 . 데비안 시스템 ls에서 bashdash쉘 의 실행 파일 크기를 비교하면 크기 가 상당히 크다는 것을 알 수 있습니다.

graeme@graeme:~$ ls -lh /bin/{ls,bash,dash}
-rwxr-xr-x 1 root root 953K Mar 30  2013 /bin/bash
-rwxr-xr-x 1 root root 115K Dec 25 20:25 /bin/dash
-rwxr-xr-x 1 root root 108K Jul 20 22:52 /bin/ls

lsGNU 버전의 모든 기능을 포함하면 bash실행 파일 크기가 10 % 증가합니다. 그것은 전체 dash껍질 과 거의 같은 크기입니다 !

대부분의 쉘 내장은 외부 실행 파일이 할 수없는 방식으로 쉘과 통합되기 때문에 (질문은 지적 cd하지만 다른 예는 killbash 작업 제어와 통합 하는 bash 버전입니다 ) 또는 구현하기가 매우 간단한 명령이기 때문에 선택됩니다. 크기 보수 대 큰 속도를 제공 ( truefalse간단한로 가져 약이다).

GNU ls는 개발주기가 길 었으며 결과를 표시하는 방법 / 방법을 사용자 정의하는 옵션을 구현할 수 있습니다. 기본적으로 내장 ls를 사용하면이 기능이 손실되거나 쉘 복잡성과 크기가 크게 증가합니다.


1

cd쉘에 내장되어 있으며, ls별도의 프로그램이 있습니다 /bin/ls.


0

이것은 당신이 찾고있는 것을합니다 :

printf "%s\n" *

또한 파일 이름을 배열에 저장할 수 있습니다.

files=(`printf "%s\n" *`)  #items are separated by whitespace
echo ${#files[*]} files
for index in ${!a[*]}
do printf "%d: %s\n" $index ${a[$index]};
done

그러나 이름의 공백
은 신경 쓰지 않습니다. 변수에 전달되고 공백을 신경 쓰십시오.

printf "%s\n" * | while read a; do echo $a; done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.