"ls *"가 "ls"보다 오래 걸리는 이유는 무엇입니까?

"ls *"가 "ls"보다 오래 걸리는 이유는 무엇입니까?

내 디렉터리에 여러 파일이 있습니다.

$ ls | wc -l
9376

ls *and를 사용할 때 왜 이렇게 큰 시차가 발생하는지 설명할 수 있는 사람이 있나요 ls?

$ time ls > /dev/null
real    0m0.118s
user    0m0.106s
sys     0m0.011s

그리고

$ time ls * > /dev/null
real    1m32.602s
user    0m0.233s
sys     0m0.438s

좋습니다. 이는 과감한 예이며 디렉터리가 GPFS(일반 병렬 파일 시스템)에 있으므로 향상될 수 있습니다. 그러나 로컬 파일 시스템에서도 상당한 속도 저하를 볼 수 있습니다.

편집하다:

$ time ls -l > /dev/null
real    0m58.772s
user    0m0.113s
sys     0m0.452s
$ time ls -l * > /dev/null
real    1m19.538s
user    0m0.252s
sys     0m0.461s

내 예에는 하위 디렉터리가 없다는 점을 추가해야 합니다.

$ diff <(ls) <(ls *)
$

답변1

인수 없이 실행 하면 ls디렉토리를 열고 모든 내용을 읽고 정렬하고 인쇄합니다.

를 실행하면 ls *먼저 쉘이 확장됩니다 . 이는 단순히 현재 디렉토리의 모든 파일을 사용하여 인수 벡터를 구축하고 를 호출하는 *것과 같습니다 . 그런 다음 해당 인수 벡터와 각 인수를 처리하고 파일을 호출하여 확인해야 합니다. 그것은 존재합니다. 그런 다음 첫 번째(간단한) 출력과 동일한 출력을 인쇄합니다 . 쉘의 큰 인수 벡터 및 합계 처리에는 많은 수의 작은 메모리 블록 할당이 포함될 수 있으며 이는 시간이 걸릴 수 있습니다. 하지만 시간이 적고 많기 때문에 메모리 할당을 위해 CPU를 사용하기 보다는 디스크를 기다리는 데 대부분의 시간을 소비하게 됩니다.lslslsaccess(2)lslssysuserreal

각 호출에서는 access(2)권한 정보를 얻기 위해 파일의 inode를 읽어야 합니다. 이는 단순히 디렉토리를 읽는 것보다 더 많은 디스크 읽기 및 탐색을 의미합니다. GPFS에서 이러한 작업의 비용이 얼마나 드는지는 모르겠지만 ls -l와일드카드 사례와 유사한 런타임 비교를 통해 표시한 것처럼 inode 정보를 검색하는 데 필요한 시간이 지배적인 것 같습니다. GPFS가 로컬 파일 시스템보다 읽기 작업당 대기 시간이 약간 더 길면 이러한 경우 대기 시간이 더 눈에 띌 것으로 예상됩니다.

와일드카드 케이스와 50% ls -l의 차이는 디스크의 inode 순서로 설명할 수 있습니다. inode를 디렉토리에 있는 파일 이름과 동일한 순서로 연속적으로 배열하고 ls -l파일을 디렉토리 순서대로 stat(2)한 후 정렬한 경우 ls -l한 번의 스캔으로 대부분의 inode를 읽을 수 있습니다. 와일드카드를 사용하면 쉘이 파일 이름을 전달하기 전에 정렬하므로 lsinode ls를 다른 순서로 읽을 수 있어 디스크 헤드 이동이 더 많아집니다.

출력 에는 time쉘 확장 와일드카드에 소요된 시간이 포함되지 않습니다.

무슨 일이 일어나고 있는지 정말로 알고 싶다면 다음을 사용하십시오 strace(1).

strace -o /tmp/ls-star.trace ls *
strace -o /tmp/ls-l-star.trace ls -l *

각 경우에 어떤 시스템 호출이 실행되고 있는지 확인하세요.

access(2)¹ 그것이 실제로 사용되는지, 아니면 다른 것인지는 알 수 없습니다 . 예를 들어 둘 다 inode 조회가 필요할 수 있습니다( inode 조회를 우회할지 stat(2)여부는 확실하지 않습니다 .)access(file, 0)

관련 정보