stat 関数と stat コマンド Linux ファイル内の [inode = インデックス ノード] の説明: inode を理解するには、ディスクと [ディレクトリ エントリ] を理解する必要があります。inode は、実際には [ディレクトリ エントリ] とディスクを接続する中間素材です。 図の大きな円はハードウェア ディスクを表し、内部の小さな円はディスクに保存されているファイルを表します。 [inode = インデックス ノード] のノード (ノード情報を運ぶ構造体は stat です。stat の定義は後述します) には次のものが含まれます。
下の図では、hello は通常のファイルであり、hello.hard は hello へのハード リンクです。 フォルダには、以下に示すように各ファイルの [ディレクトリ項目] が含まれています。 [ディレクトリ項目] には次のものが含まれます。
ファイルの inode を表示するにはどうすればいいですか? -iオプションを使用する ls -li ファイル名 実行結果:
hello と hello.hard の inode (3801352) は同じであることがわかります。つまり、ディスクには 1 つのコピーのみが保存されていることを意味します。 ディレクトリ項目を表示するにはどうすればいいですか?下のスクリーンショットに示すように、emacs または vim を使用してディレクトリ (lianxi1) を開きます。しかし、ファイルの inode は表示されません。 1. stat 関数: 指定されたファイルのファイル属性を取得します。ファイル属性は構造体 stat に格納されます。 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *pathname, struct stat *statbuf); int fstat(int fd, struct stat *statbuf); int lstat(const char *pathname, struct stat *statbuf); struct stat 構造: 構造体stat{ dev_t st_dev; /* ファイルを含むデバイスのID */ ino_t st_ino; /* iノード番号 */ mode_t st_mode; /* ファイルタイプとモード */ nlink_t st_nlink; /* ハードリンクの数 */ uid_t st_uid; /* 所有者のユーザーID */ gid_t st_gid; /* 所有者のグループID */ dev_t st_rdev; /* デバイスID(特殊ファイルの場合) */ off_t st_size; /* 合計サイズ(バイト単位) */ blksize_t st_blksize; /* ファイルシステムI/Oのブロックサイズ */ blkcnt_t st_blocks; /* 割り当てられた 512B ブロックの数 */ /* Linux 2.6以降、カーネルはナノ秒をサポートしています 次のタイムスタンプ フィールドの精度。 Linux 2.6 以前の詳細については、「注記」を参照してください。 */ struct timespec st_atim; /* 最終アクセス時刻 */ struct timespec st_mtim; /* 最終変更時刻 */ struct timespec st_ctim; /* 最後のステータス変更の時刻 */ #define st_atime st_atim.tv_sec /* 下位互換性 */ #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec }; st_dev: デバイスID。一般的には使用されない
0-2ビット: その他のユーザー権限 ファイル タイプ マクロは次のとおりです (以下の数字は 8 進数です)。
ファイルの種類を判別する関数。true、false を返す。 S_ISREG(stat.st_mode)は通常のファイルですか? S_ISDIR(stat.st_mode)ディレクトリ? S_ISCHR(stat.st_mode) 文字デバイス? S_ISBLK(stat.st_mode) ブロックデバイス? S_ISFIFO(m) FIFO (名前付きパイプ)? S_ISLNK(stat.st_mode) シンボリックリンクですか? (POSIX.1-1996 には存在しません。) S_ISSOCK(stat.st_mode) ソケット? (POSIX.1-1996 にはありません。) ファイル権限のマクロは次のとおりです。 S_ISUID 04000 ユーザーID設定ビット S_ISGID 02000 グループIDビットの設定(下記参照) S_ISVTX 01000 スティッキービット(下記参照) S_IRWXU 00700 所有者は読み取り、書き込み、実行権限を持っています S_IRUSR 00400 所有者は読み取り権限を持っています S_IWUSR 00200 所有者に書き込み権限がある S_IXUSR 00100 所有者に実行権限がある S_IRWXG 00070 グループには読み取り、書き込み、実行の権限があります S_IRGRP 00040 グループに読み取り権限がある S_IWGRP 00020 グループには書き込み権限があります S_IXGRP 00010 グループには実行権限があります S_IRWXO 00007 その他(グループ外)は読み取り、書き込み、 実行権限 S_IROTH 00004 他の人は読み取り権限を持っています S_IWOTH 00002 他の人は書き込み権限を持っています S_IXOTH 00001 他の人に実行権限がある
構造体タイムスペック{ __kernel_time_t tv_sec; /* 秒 */現在の時刻から 1970.1.1 00:00:00 までの秒数 long tv_nsec; /* ナノ秒 *//ナノ秒 (どこからどこまでかは不明) }; 1s 秒 = 1000ms ミリ秒 1ms ミリ秒 = 1000us マイクロ秒 1us マイクロ秒 = 1000ns ナノ秒 パス名: ファイル名 戻り値: 成功の場合は 0、失敗の場合は -1、エラーが設定されます 例: statbuf は構造体 stat であり、st_mode は 10 進数であることがわかります。 st_モード gdb を使用して st_mode を表示すると、返された st_mode が 10 進数であることがわかります。gdb の [p/o] (o は 8 進数表現を表します) コマンドを使用して、10 進数の 33204 を 8 進数の [0100664] に変換します。最初の 0 は 8 進数を表し、最後の 3 桁の [100] はファイルの種類を表します。上記の説明から、[100] は通常のファイルを表し、最後の 3 桁の [664] はこのファイルの権限 (このユーザー: rw-、グループ ユーザー: rw-、他のユーザー: r--) を表すことがわかります。したがって、st_mode からファイルの種類と権限設定を知ることができます (16 ビットのみが使用されるため、スペースが大幅に節約されます。すばらしい!) st_uid st_gid st_uid と st_gid が 1000 であることがわかりますが、この 1000 はユーザーとどのように対応しているのでしょうか。/etc/passwd ファイルを確認すると、ys に使用されている uid と gid が両方とも 1000 であるため、対応していることがわかります。 stat コマンドは stat 関数に対応しており、実行結果は次のようになります。 ys@ys-VirtualBox:~/lianxi1$ 統計 こんにちは ファイル: hello サイズ: 11 ブロック: 8 IO ブロック: 4096 通常ファイル デバイス: 801h/2049d Inode: 3801352 リンク: 2 アクセス: (0764/-rwxrw-r--) ユーザー ID: ( 1000/ ys) グループ ID: ( 1000/ ys) アクセス: 2019-04-24 17:02:39.199461489 +0800 修正: 2019-04-24 16:54:16.407461489 +0800 変更: 2019-04-24 17:03:44.927461489 +0800 2. getpwuid 関数: /etc/passwd ファイル内の指定された uid を持つ行を返し、この行の情報を構造体 passwd に格納します。戻り値はポインターですが、free関数を呼び出す必要はありません。 #include <sys/types.h> #include <pwd.h> 構造体passwd *getpwnam(const char *name); 構造体passwd *getpwuid(uid_t uid); 構造体passwd{ char *pw_name; /* ユーザー名 */ char *pw_passwd; /* ユーザパスワード */ uid_t pw_uid; /* ユーザーID */ gid_t pw_gid; /* グループID */ char *pw_gecos; /* ユーザー情報 */ char *pw_dir; /* ホームディレクトリ */ char *pw_shell; /* シェルプログラム */ }; 3. getgrgid 関数: /etc/group ファイル内の指定された gid を持つ行を返し、この行の情報を構造体 group に格納します。戻り値はポインターですが、free関数を呼び出す必要はありません。 #include <sys/types.h> #include <grp.h> 構造体グループ *getgrnam(const char *name); 構造体グループ *getgrgid(gid_t gid); 構造体グループ{ char *gr_name; /* グループ名 */ char *gr_passwd; /* グループパスワード */ gid_t gr_gid; /* グループID */ char **gr_mem; /* NULLで終わるポインタの配列 グループメンバーの名前 */ }; 4. localtime 関数: stat 関数から取得した st_mtim.tv_sec (現在の時刻から 1970.1.1 00:00:00 までの秒数) を渡して、構造体 tm を取得します。戻り値はポインターですが、free関数を呼び出す必要はありません。 #include <time.h> 構造体 tm *localtime(const time_t *timep); 構造体tm{ int tm_sec; /* 秒 (0-60) */ int tm_min; /* 分 (0-59) */ int tm_hour; /* 時間 (0-23) */ int tm_mday; /* 月の日付 (1-31) */ int tm_mon; /* 月 (0-11) */ int tm_year; /* 年 - 1900 */ int tm_wday; /* 曜日 (0-6、日曜日 = 0) */ int tm_yday; /* 年間の日数 (0-365、1 月 1 日 = 0) */ int tm_isdst; /* 夏時間 */ }; 5. lstat 関数: stat はソフト リンクに遭遇すると、ソース ファイルまで遡って侵入しますが、lstat は侵入しません。 例: ls -l ファイルを模倣する #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <文字列.h> #include <pwd.h>//pwuid を取得する #include <stdlib.h> #include <time.h>//localtime #include <grp.h> //grgidを取得する int main(int argc, char* argv[]){ 構造体 stat sbuf; //stat(argv[1], &sbuf); lstat(argv[1], &sbuf); 文字str[11] = {0}; memset(str, '-', (strのサイズ - 1)); //ファイルタイプ if(S_ISREG(sbuf.st_mode)) str[0] = '-'; S_ISDIR(sbuf.st_mode)の場合、str[0] = 'd'; S_ISCHR(sbuf.st_mode)の場合、str[0] = 'c'; S_ISBLK(sbuf.st_mode)の場合、str[0] = 'b'; S_ISFIFOの場合、str[0]は'p'です。 S_ISLNK(sbuf.st_mode)の場合、str[0] = 'l'; S_ISSOCK(sbuf.st_mode)の場合、str[0] = 's'; //このユーザーのファイル権限 if(sbuf.st_mode & S_IRUSR) str[1] = 'r'; sbuf.st_mode と S_IWUSR の場合、str[2] は 'w' になります。 sbuf.st_mode & S_IXUSRの場合、str[3] = 'x'; //このユーザーのグループのファイル権限 if(sbuf.st_mode & S_IRGRP) str[4] = 'r'; sbuf.st_mode と S_IWGRP の場合、str[5] は 'w' になります。 sbuf.st_mode & S_IXGRPの場合、str[6] = 'x'; //他のユーザーのファイル権限 if(sbuf.st_mode & S_IROTH) str[7] = 'r'; sbuf.st_mode と S_IWOTH の場合、str[8] は 'w' になります。 sbuf.st_mode と S_IXOTH の場合、str[9] は 'x' になります。 文字ymd[20] = {0}; //日付と時刻を取得します struct tm* tm = localtime(&sbuf.st_atim.tv_sec); sprintf(ymd, "%2d月%2d %02d:%02d", tm->tm_mon + 1, tm->tm_mday, tm->tm_hour + 1、tm->tm_sec); //-rw-r--r-- 1 ys ys 134 4月25日 09:21 st2.c printf("%s %ld %s %s %ld %s %s\n", str, sbuf.st_nlink, getpwuid(sbuf.st_uid)->pw_name、getgrgid(sbuf.st_gid)->gr_name、 sbuf.st_size、ymd、argv[1]); 0を返します。 } 6. アクセス機能: 指定されたファイルに対するプログラムを呼び出すユーザーの権限を決定します (読み取り可能? 書き込み可能? 実行可能?) #include <unistd.h> int access(const char *パス名、intモード); 例: #include <stdio.h> #include <unistd.h>//アクセス int main(int argc, char* argv[]){ (access(argv[1], R_OK) == 0の場合) printf("読み取り成功\n"); (アクセス(argv[1], W_OK) == 0)の場合 printf("書き込みOK\n"); アクセス(argv[1], X_OK) == 0の場合 printf("exe ok\n"); アクセス(argv[1], F_OK) == 0の場合 printf("存在します\n"); } まずls -lを使用して/usr/include/time.hファイルの権限を確認します。結果は次のとおりです。 ys@ys-VirtualBox:~/lianxi$ ls -l /usr/include/time.h -rw-r--r-- 1 ルート ルート 10360 2018年4月17日 /usr/include/time.h ユーザー ys としてサンプル プログラムを実行し、/usr/include/time.h ファイルを表示します。結果は次のようになります。 time.h は root ユーザーに属し、他のユーザーにとっては [r--] であるため、次の結果が得られます。 ys@ys-VirtualBox:~/lianxi$ ./ac /usr/include/time.h 読んでOK 存在する 引き続きユーザー ys で実行し、sudo を追加すると、結果は次のようになります。結果は root ユーザーの場合と同じです。 sudo が追加されたため、root ユーザーがプログラムされました。 ys@ys-VirtualBox:~/lianxi$ sudo ./ac /usr/include/time.h [sudo] ysのパスワード: 読んでOK 書いてOK 存在する 7. 切り捨て関数: ファイルサイズを切り捨てて拡張する #include <unistd.h> #include <sys/types.h> int 切り捨て(const char *path, off_t 長さ); パス: ファイル 8. リンク機能: ハードリンクを作成する #include <unistd.h> int link(const char *oldpath, const char *newpath); 戻り値: 成功した場合は 0 を返し、失敗した場合は -1 を返し、errno を設定します。 9. シンボリックリンク機能: ソフトリンクを作成する #include <unistd.h> int symlink(const char *target, const char *linkpath); 戻り値: 成功した場合は 0 を返し、失敗した場合は -1 を返し、errno を設定します。 10. readlink 関数: ソフト リンクに対応する実際のファイルを検索し、ファイル名を buf に格納します。注意: ハードリンクは機能しません。 #include <unistd.h> ssize_t readlink(const char *pathname, char *buf, size_t bufsiz); 戻り値: 成功した場合は、buf に書き込まれたバイト数を返します。失敗した場合は、-1 を返して errno を設定します。 11. リンク解除機能: ソフトリンクとハードリンクを削除し、ファイルを削除することもできます。 #include <unistd.h> int unlink(const char *パス名); 戻り値: 成功した場合は 0 を返し、失敗した場合は -1 を返し、errno を設定します。 特別な使用方法があります。次のオープン コードは、hello ファイルを作成し、unlink で直接削除しようとしますが、正常に書き込みができ、ret は 0 より大きく、プログラムの実行後に hello ファイルが作成されていないことがわかります。 結論: unlink を実行すると、カウントは 0 になりますが、他のプロセスがまだこのファイルを参照していることがわかります。この時点では、unlink はこのファイルを削除しません。このプロセスが終了したら削除されるため、次の書き込みコードが正常に記述できます。 #include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> int main(){ int fd = open("hello", O_WRONLY | O_CREAT, 0666); リンクを解除します("hello"); int ret = write(fd, "aaa", 4); if(ret > 0){ printf("書き込みOK\n"); } } 12. chown関数: ファイルが属するユーザーとグループを変更する #include <unistd.h> int chown(const char *パス名、uid_t 所有者、gid_t グループ); パス名: ファイル 所有者: ユーザーID (数値) /etc/passwd グループ: グループID (数値) /etc/group 戻り値: 成功した場合は 0、失敗した場合は -1。 13. 名前変更機能: 名前変更 #include <stdio.h> int rename(const char *oldpath, const char *newpath); oldpath: 元のファイル名またはディレクトリ newpath: 新しいファイル名またはディレクトリ 戻り値: 成功した場合は 0、失敗した場合は -1。 14. getcwd関数: 現在の作業ディレクトリを取得する #include <unistd.h> char *getcwd(char *buf, size_t サイズ); buf: 現在の作業ディレクトリ サイズ: バッファサイズ 戻り値: 成功した場合は現在の作業ディレクトリを返します。失敗した場合は NULL を返します。 15. chdir関数: プロセスの作業ディレクトリを変更する #include <unistd.h> int chdir(const char *path); パス: 対象の作業ディレクトリ 戻り値: 成功の場合は 0、失敗の場合は -1 16. mkdir関数: ディレクトリを作成する #include <sys/stat.h> #include <sys/types.h> int mkdir(const char *パス名, mode_t モード); パス名: ターゲット作業ディレクトリ モード: mode & ~umask & 0777 。 x 権限を持っていない場合は、このディレクトリに cd できないことに注意してください。戻り値: 成功の場合は 0、失敗の場合は -1 17. rmdir 関数: ディレクトリを削除します。ディレクトリは空のディレクトリ、つまり、その中にファイルが存在しないディレクトリである必要があります。 #include <unistd.h> int rmdir(const char *パス名); 18. opendir関数: ディレクトリを開く #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); 名前: ディレクトリ名 戻り値: ディレクトリストリームへのポインタ 19. readdir関数: ディレクトリの読み取り #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); dirp: opendir関数の戻り値 戻り値: dirent 構造体。これは、前述の「ディレクトリ エントリ」として理解できます。NULL は、最後まで読み取るかエラーを意味します。NULL 以外は、ディレクトリ エントリの内容を意味します。 20. closedir関数: ディレクトリを閉じる #include <sys/types.h> #include <dirent.h> int closedir(DIR *dirp); dirp: opendir関数の戻り値 21. strerron 関数: errno に対応するテキスト情報を出力します。 #include <文字列.h> char *strerror(int errnum); errnumマクロは、ファイル/usr/include/asm-generic/errno.hに配置されます。 例: #include <文字列.h> #include <stdio.h> #include <asm-generic/errno.h> //EDEADLK int main(){ char* buf = strerror(EDEADLK); printf("%s\n", buf); // リソースのデッドロックを回避 } 22. dup および dup2 関数: ファイル記述子のリダイレクト #include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); dup: open と同様に、最初に新しいファイル記述子を開き、新しいファイル記述子も oldfd が指す場所を指すようにします。成功した場合は新しく開かれたファイル記述子を返します。失敗した場合は -1 を返します。 dup2: 最初に newfd へのポインタを削除し、次に newfd が oldfd が指す場所を指すようにします。成功した場合は newfd を返し、失敗した場合は -1 を返します。 例: printf を 2 回呼び出します。最初の printf はコンテンツをファイルに書き込み、2 番目の printf はコンテンツを画面に出力します。 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(){ int oldfd = dup(STDOUT_FILENO); int fd = open("www", O_WRONLY | O_CREAT, 0666); dup2(fd, STDOUT_FILENO); printf("aaa\n"); fflush(標準出力); int ret = dup2(oldfd、STDOUT_FILENO); //int ret = dup2(oldfd, 6); //perror("重複2:"); printf("reg:%d\n", ret); printf("aaa\n"); 閉じる(fd); } Linux の stat 関数と stat コマンドの詳細な使用法に関するこの記事はこれで終わりです。Linux の stat 関数と stat コマンドに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Excel をインポートするときに js で時間を変換する正しい方法について
目次1. フロントエンド制御1. router.js ファイル内 (router.js にそれぞれ静...
1.Docer CEをインストールして使用するこの記事では、CentOS 7 を例に Docker ...
目次予備的注釈問題の再現データ削除の原則データの再利用どの操作がデータホールの原因になりますか?表領...
HTML メタビューポート属性の説明ビューポートとはモバイル ブラウザは、Web ページを仮想の「ウ...
1. はじめに以前は、Python アプリケーションの作成を開始したい場合、最初のステップはマシンに...
この記事では、MySQL 5.6.37のダウンロード、インストール、設定のチュートリアルを参考までに...
プロパティやイベントがあるにもかかわらず、JavaScript で子コンポーネントに直接アクセスする...
目次序文レンダリングの役割レンダリング機能の説明レンダリングとテンプレートの違いレンダリング例要約す...
半透明の境界線結果: 実装コード: <div> 半透明の境界線が見えますか? </...
序文JavaScript では、document.querySelector("#demo...
Dockerエラー1. 原因を確認するdocker ログ ネクサス2. エラーの原因OpenJDK ...
目次1. 関数の抽出2. 重複した条件付きスニペットを結合する3. 条件分岐文を関数に抽出する4. ...
CSS 属性セレクターは素晴らしいです。大量のクラス名を追加することを回避し、コード内の問題を指摘す...
目次cgroupとはcgroupの構成cgroupが提供する機能cgroup 内の CPU を制限す...
目次1. コマンド2. docker-compose.yml 3. Dockerファイル4. 直接変...