tar가 파일에서 작동하는 순서는 어떻게 결정됩니까?


15
$ touch dir/{{1..8},{a..p}}
$ tar cJvf file.tar.xz dir/
dir/
dir/o
dir/k
dir/b
dir/3
dir/1
dir/i
dir/7
dir/4
dir/e
dir/a
dir/g
dir/2
dir/d
dir/5
dir/8
dir/c
dir/n
dir/f
dir/h
dir/6
dir/l
dir/m
dir/j
dir/p

나는 알파벳이 될 것으로 예상했을 것입니다. 그러나 분명히 그렇지 않습니다. 공식은 무엇입니까?

답변:


14

으로 @samiam는 진술했다 목록을 통해 반 임의의 순서로 당신에게 반환됩니다 readdir(). 다음을 추가하겠습니다.

반환 된 목록은 내가 디렉토리 순서라고 부르는 것입니다. 이전 파일 시스템에서 순서는 종종 디렉토리 테이블의 파일 항목이 추가 된 작성 순서입니다. 물론 디렉토리 항목을 삭제하면이 항목이 재활용되므로 저장된 후속 파일이 이전 항목을 대체하므로 순서는 더 이상 작성 시간을 기준으로하지 않습니다.

디렉토리 데이터 구조가 검색 트리 또는 해시 테이블을 기반으로하는 최신 파일 시스템에서는 실제로 순서를 예측할 수 없습니다.

touch 명령을 실행할 때 생성 된 파일을 찌르면 다음 inode가 할당 된 것으로 나타납니다.

$ touch dir/{{1..8},{a..p}}
$ stat --printf="%n -- %i\n" dir/*
dir/1 -- 10883235
dir/2 -- 10883236
dir/3 -- 10883242
dir/4 -- 10883243
dir/5 -- 10883244
dir/6 -- 10883245
dir/7 -- 10883246
dir/8 -- 10883247
dir/a -- 10883248
dir/b -- 10883249
dir/c -- 10883250
dir/d -- 10883251
dir/e -- 10883252
dir/f -- 10883253
dir/g -- 10883254
dir/h -- 10883255
dir/i -- 10883256
dir/j -- 10883299
dir/k -- 10883302
dir/l -- 10883303
dir/m -- 10883311
dir/n -- 10883424
dir/o -- 10883426
dir/p -- 10883427

터치에 의해 사용 된 괄호 확장은 파일 이름을 알파벳 순서로 생성하므로 HDD에 기록 될 때 순차적 inode 번호가 할당됩니다. 그러나 디렉토리의 순서에는 영향을 미치지 않습니다.

tar명령을 여러 번 실행 하면 목록에 순서가 있음을 나타내는 것 같습니다. 명령을 여러 번 실행하면 매번 동일한 목록이 생성되기 때문입니다. 여기에서 나는 그것을 100 번 실행 한 다음 실행을 비교했으며 모두 동일합니다.

$ for i in {1..100};do tar cJvf file.tar.xz dir/ > run${i};done
$ for i in {1..100};do cmp run1 run${i};done
$ 

전략적으로 say를 삭제 dir/e한 다음 새 파일을 추가하면 dir/ee이 새 파일이 dir/e디렉토리 항목 테이블에서 이전에 차지한 위치를 차지 했음을 알 수 있습니다 .

$ rm dir/e
$ touch dir/ee

이제 for위 의 루프 중 하나의 출력을 유지합시다 .

$ mv run1 r1A

이제 명령을 다시 100 번 실행하는 for루프를 tar다시 실행하고이 두 번째 실행을 이전 실행과 비교하십시오.

$ sdiff r1A run1
dir/                                dir/
...
dir/c                               dir/c
dir/f                               dir/f
dir/e                             | dir/ee
dir/o                               dir/o
dir/2                               dir/2
...

우리는 통지 dir/ee취한 dir/e디렉토리 테이블의 장소.


와우, 이것은 정말 좋은 답변입니다. 디렉토리가 주어지면 tar가 하위 항목을 처리하는 순서가 무엇인지 알 수있는 방법이 있습니까? 나는 그것에 대해 확신하지 않지만 다음은 어떻게 보입니까? stat --printf='%i\t-- %n\n' * | sort -n | sed 's/.*\t-- //'
John

2
파일 시스템에 따라 다릅니다. 나는 파일 해시 또는 일부 등 (즉, 파일 시스템이 동적으로 아이 노드를 생성하기 때문에 나는 다른 감각을 기존의 ReiserFS에 주문을 가지고)의 순서에 따라 그들을 선별 BTREE 형 파일 시스템을 상상할 수
samiam

1
@samiam-맞습니다.이 답변은 '디렉토리 순서'가 '디렉토리 테이블의 파일 항목이 추가 된 생성 순서'라고 주장하며 그 자체가 tar 파일 내용의 일부를 보여줍니다. 현재 Linux ext * 파일 시스템을 포함한 많은 파일 시스템은 일부 오래된 파일 시스템과 같은 단순한 순차 테이블이 아니라 디렉토리 구조에서 트리 및 / 또는 해시를 사용합니다.
Michał Politowski

3
@ 존 ls -f이나 ls -U또는find -maxdepth 1

1
@ 존 -f플래그는 고대 유닉스에서 나왔습니다 . 그 목적은 빨랐다. 정렬, 도트 파일 건너 뛰기 및 기타 몇 가지 기능을 비활성화했습니다. 이 -U플래그는 다른 부작용없이 정렬을 비활성화 할 수있는 GNU 혁신입니다.

8

readdir()원래. 타르 파일이 디렉토리에 무엇을 발견하면 직접 통해 나열하는 파일에 대한 커널 요청 opendir()에 의해 다음을 readdir(). readdir()특정 순서로 파일을 반환하지 않습니다. 파일 순서는 Linux 커널에서 사용하는 파일 시스템에 따라 다릅니다.

아아, tar하위 디렉토리에서 파일을 정렬 하는 옵션은 아닙니다 (파일을 추가하는 것은 독자의 연습으로 남습니다).


1
inode의 값을 기준으로 검색하는지 궁금합니다.
slm

1
@slm f_op->iterateglibc가 readdir()결국 via로 필터링 하는 호출 getdents()은 파일 시스템 특정 구현에 매핑됩니다. 더 높은 수준 dirent에서 fs 구현이 반환 하는 순서를 바꾸는 것을 볼 수 없습니다 .
Matt

@slm 아니요, inode 값이 디렉토리 순서에 영향을 미치는 파일 시스템에 대해 들어 본 적이 없습니다.
Gilles 'SO- 악마 그만해'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.