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 에는 inode
stat/lstat(및 64비트 변형)에서 반환된 16비트 필드가 있습니다. 9비트 는 rwxrwxrwx 권한에 사용되고 3비트는 및 에 사용됩니다 sticky bit
. 나머지 4비트는 일부 유형 정보를 인코딩하는 데 사용됩니다. 이는 일반 파일, 디렉터리, 블록 또는 문자 장치, 명명된 파이프 등이라고 말할 수 있습니다.set group id (sgid) bit
set 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 시스템 호출을 사용하여 자세한 정보를 수집합니다. 구조는 여기에 정의되어 있습니다. 통계 파일을 확인하는 경우:stat
file
stat()
/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
포크"에는 확장 속성이 포함되어 있습니다.