ls 또는 stat와 같은 명령은 파일 형식을 어떻게 구별합니까?

ls 또는 stat와 같은 명령은 파일 형식을 어떻게 구별합니까?

ls 또는 stat와 같은 명령은 객체가 파일인지 디렉토리인지에 관계없이 파일 유형을 어떻게 구별합니까?

stat예를 들어, 저는 디렉터리도 파일이라는 사실을 고려하여 이 두 개체를 만들었습니다. 몇 가지 특별한 규칙을 사용하여 출력에서 ​​"디렉터리" 및 "일반 빈 파일"로 표시하는 방법을 알고 싶습니다. ""명령.

$ mkdir testdir;touch testfile
$ stat testdir | head -2;stat testfile | head -2
 File: `testdir'
 Size: 4096            Blocks: 8          IO Block: 4096   directory
 File: `testfile'
 Size: 0               Blocks: 0          IO Block: 4096   regular empty file

나중에 testdir 디렉토리와 testfile 파일의 stat를 각각 실행할 때 strace를 수행했습니다. 추적 출력에서 ​​나는 이것을 발견했습니다.

lstat("testdir/", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0

그리고

lstat("testfile", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0

st_mode누군가이 값 S_IFDIR합계 를 얻는 방법을 알려주십시오 S_IFREG.

혼란스러워 보일 수도 있습니다.

답변1

여러분의 혼란을 해소해 보도록 하겠습니다. st_mode 에는 inodestat/lstat(및 64비트 변형)에서 반환된 16비트 필드가 있습니다. 9비트 는 rwxrwxrwx 권한에 사용되고 3비트는 및 에 사용됩니다 sticky bit. 나머지 4비트는 일부 유형 정보를 인코딩하는 데 사용됩니다. 이는 일반 파일, 디렉터리, 블록 또는 문자 장치, 명명된 파이프 등이라고 말할 수 있습니다.set group id (sgid) bitset userid (suid) bit

따라서 디렉터리를 생성하는 경우 이 4비트는 디렉터리임을 나타냅니다. strace 출력에서 ​​이를 확인할 수 있습니다.

lstat("testdir/", {st_mode=S_IFDIR|0775, st_size=4096, ...})
                           ^^^^^^^ 4 bits showing the type is directory
                                   ^ 3 bits (this is octal) for suid/sgid/sticky
                                    ^^^ rwxrwxrwx info.

답변2

command 를 사용 하고 ls내부적 으로 C 시스템 호출을 사용하여 자세한 정보를 수집합니다. 구조는 여기에 정의되어 있습니다. 통계 파일을 확인하는 경우:statfilestat()

  • /usr/include/bits/stat.h
  • /usr/include/linux/stat.h

다음 비트가 정의됩니다:

/* Encoding of the file mode.  */

#define __S_IFMT        0170000 /* These bits determine file type.  */

/* File types.  */
#define __S_IFDIR       0040000 /* Directory.  */
#define __S_IFCHR       0020000 /* Character device.  */
#define __S_IFBLK       0060000 /* Block device.  */
#define __S_IFREG       0100000 /* Regular file.  */
#define __S_IFIFO       0010000 /* FIFO.  */
#define __S_IFLNK       0120000 /* Symbolic link.  */
#define __S_IFSOCK      0140000 /* Socket.  */

the stat function will check the POSIX macros and compare to see if it is a regular file/ directory

#define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)
#define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK)

이것이 st_mode이러한 값 S_IFDIR의 합을 구하는 방법 입니다 S_IFREG.

참고로... inode가 파일 유형을 인식하는 방법에 대한 주요 질문 중 하나는 다음과 같습니다.

XFS 파일 시스템의 경우 inode 데이터 구조는 세 부분으로 나뉩니다.

  • di_core(96바이트)
  • di_u데이터 포크
  • di_a확장된 속성 포크

코어에는 인덱스 노드가 나타내는 것, 통계, 데이터 및 속성 분기를 설명하는 정보가 포함됩니다. 여기의 파일 형식은 di_core.di_mode일반 파일, 디렉터리, 링크 등으로 제어됩니다.

"데이터 di_u포크"에는 인덱스 노드와 관련된 일반 데이터가 포함됩니다.

"속성 di_a포크"에는 확장 속성이 포함되어 있습니다.

관련 정보