循序漸進學unix——上機記錄(一)

    Unix上機課已經進行5次了,信息量越來越大,需要記的東西也越來越多。於是決定把一些重要的東西記在這裏跟大家分享。


在法國學計算機一個很大的感觸就是實踐所佔的比重相當大,大課的信息量極大,很難記住什麼東西,但是與之輔助的小課實在是十分奏效。小課以20人的小班爲單位,這就是人少的好處,能保證每個人都掌握相關的知識。這邊的課確實比在國內深多了,能看出老師確實有很高的水平,講的很深很細緻。


Unix系統課已經上了很多節,這裏只記錄上機課的一些個人認爲重要的知識點。前兩節小課主題是Bash 基本命令,再此不記錄了,這裏主要涉及通過unix下的c語言編程瞭解系統原理。


第一課

1, 寫一個c程序,打印從終端傳入的參數。注意當參數爲*結果。

       主函數生命爲 void main(int argc, char ** argv)即可。argc爲參數個數, argv爲參數列表,注意argv[0]爲命令本身,之後才爲真正參數。

2,寫一個程序,實現與"ls -il"相同的功能,即輸出當前目錄所有文件的有用信息,如訪問模式,鏈接個數,最近修改時間等等。此函數利用了第一題的知識,即*會被翻譯成當前目錄下的所有文件。下面的程序在終端調用時參數爲*。

     主要使用stat()函數。見man lstat, 需要詳細閱讀。stat能把相應文件的所有信息返回至一個結構體裏。獲得所有者用戶名時用到getpwuid,組用戶名時用到getgrgid, 相關函數還有ctime. 代碼:

   

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>



int main(int argc, char **argv)

{
	int i;

	struct stat fileStat
;
	struct passwd *pwd;

	struct group *grp;

	char date[20];
	
	// pour tous les noms de fichiers passés en paramètres
	
for(i = 1; i < argc; i++)
	
{
		// collecte des infos
		
	if(lstat(argv[i], &fileStat)) 
	{ 
		perror("stat"); 
		exit(errno); 
	}
		
		// numéro d'I-noeud :I-noeud個數
		printf("%d ", (int)fileStat.st_ino);
		
		// mise en forme des permissions 各種權限
		switch(fileStat.st_mode & S_IFMT)
		{	
			case S_IFSOCK : printf("s"); break;
			case S_IFLNK : printf("l"); break;
			case S_IFREG : printf("-"); break;
			case S_IFBLK : printf("b"); break;
			case S_IFDIR : printf("d"); break;
			case S_IFCHR : printf("c"); break;
			case S_IFIFO : printf("p"); break;
			default : printf("?");
		} 

		if((fileStat.st_mode & S_IRUSR) == S_IRUSR) printf("r"); else printf("-");
		if((fileStat.st_mode & S_IWUSR) == S_IWUSR) printf("w"); else printf("-");
		if((fileStat.st_mode & S_IXUSR) == S_IXUSR) 
			if((fileStat.st_mode & S_ISUID) == S_ISUID) printf("s"); else printf("x");
		else
			if((fileStat.st_mode & S_ISUID) == S_ISUID) printf("S"); else printf("-");
			
		if((fileStat.st_mode & S_IRGRP) == S_IRGRP) printf("r"); else printf("-");
		if((fileStat.st_mode & S_IWGRP) == S_IWGRP) printf("w"); else printf("-");
		if((fileStat.st_mode & S_IXGRP) == S_IXGRP)
			if((fileStat.st_mode & S_ISGID) == S_ISGID) printf("s"); else printf("x");
		else
			if((fileStat.st_mode & S_ISGID) == S_ISGID) printf("S"); else printf("-");

		if((fileStat.st_mode & S_IROTH) == S_IROTH) printf("r"); else printf("-");
		if((fileStat.st_mode & S_IWOTH) == S_IWOTH) printf("w"); else printf("-");
		if((fileStat.st_mode & S_IXOTH) == S_IXOTH)
			if((fileStat.st_mode & S_ISVTX) == S_ISVTX) printf("t"); else printf("x");
		else
			if((fileStat.st_mode & S_ISVTX) == S_ISVTX) printf("T"); else printf("-");

		// nombre de liens dur 硬鏈接個數
		
printf(" %d ", (int)fileStat.st_nlink);
		
		// nom du propriétaire 所有者用戶名
		if ((pwd = getpwuid(fileStat.st_uid)) != NULL)
			printf("%s ", pwd->pw_name);
		else
			printf("%d ", fileStat.st_uid);
		
		// nom du groupe  組用戶名
		if ((grp = getgrgid(fileStat.st_gid)) != NULL)
			printf("%s ", grp->gr_name);
		else
			printf("%d ", fileStat.st_gid);
		
		// taille du fichier en octets 文件大小
		printf("%d ", (int)fileStat.st_size);
		
		// date de dernière modification 修改時間
		strftime(date, 20, "%Y-%m-%d %H:%M", gmtime(&fileStat.st_mtime));
		printf("%s ", date);
		
		// nom du fichier et saut de ligne 文件名
		printf("%s\n", argv[i]);
	}

	return 0;
}

3,如果不使用*,要如何遍歷當前目錄下的文件?

    涉及到man opendir。

   

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <dirent.h>

int main(int argc, char **argv)
{
	DIR *directory;
	struct dirent *file;
	struct stat fileStat;
	struct passwd *pwd;
	struct group *grp;
	char date[20];
	
	// le nom du répertoir à lire doit être passé en premier paramètre
	if(argc < 2) exit(-1);
	
	// ouverture du répertoire
	if((directory = opendir(argv[1])) == NULL) { perror("opendir"); exit(errno); }
	
	// pour tous les fichiers du répertoire
	while((file = readdir(directory)) != NULL)
	{
		// collecte des infos
		if(lstat(file->d_name, &fileStat)) { perror("stat"); exit(errno); }
		
		// numéro d'I-noeud
		printf("%d ", (int)fileStat.st_ino);
		
		// mise en forme des permissions
		switch(fileStat.st_mode & S_IFMT)
		{	
			case S_IFSOCK : printf("s"); break;
			case S_IFLNK : printf("l"); break;
			case S_IFREG : printf("-"); break;
			case S_IFBLK : printf("b"); break;
			case S_IFDIR : printf("d"); break;
			case S_IFCHR : printf("c"); break;
			case S_IFIFO : printf("p"); break;
			default : printf("?");
		} 

		if((fileStat.st_mode & S_IRUSR) == S_IRUSR) printf("r"); else printf("-");
		if((fileStat.st_mode & S_IWUSR) == S_IWUSR) printf("w"); else printf("-");
		if((fileStat.st_mode & S_IXUSR) == S_IXUSR) 
			if((fileStat.st_mode & S_ISUID) == S_ISUID) printf("s"); else printf("x");
		else
			if((fileStat.st_mode & S_ISUID) == S_ISUID) printf("S"); else printf("-");
			
		if((fileStat.st_mode & S_IRGRP) == S_IRGRP) printf("r"); else printf("-");
		if((fileStat.st_mode & S_IWGRP) == S_IWGRP) printf("w"); else printf("-");
		if((fileStat.st_mode & S_IXGRP) == S_IXGRP)
			if((fileStat.st_mode & S_ISGID) == S_ISGID) printf("s"); else printf("x");
		else
			if((fileStat.st_mode & S_ISGID) == S_ISGID) printf("S"); else printf("-");

		if((fileStat.st_mode & S_IROTH) == S_IROTH) printf("r"); else printf("-");
		if((fileStat.st_mode & S_IWOTH) == S_IWOTH) printf("w"); else printf("-");
		if((fileStat.st_mode & S_IXOTH) == S_IXOTH)
			if((fileStat.st_mode & S_ISVTX) == S_ISVTX) printf("t"); else printf("x");
		else
			if((fileStat.st_mode & S_ISVTX) == S_ISVTX) printf("T"); else printf("-");

		// nombre de liens dur
		printf(" %d ", (int)fileStat.st_nlink);
		
		// nom du propriétaire
		if ((pwd = getpwuid(fileStat.st_uid)) != NULL)
			printf("%s ", pwd->pw_name);
		else
			printf("%d ", fileStat.st_uid);
		
		// nom du groupe
		if ((grp = getgrgid(fileStat.st_gid)) != NULL)
			printf("%s ", grp->gr_name);
		else
			printf("%d ", fileStat.st_gid);
		
		// taille du fichier en octets
		printf("%d ", (int)fileStat.st_size);
		
		// date de dernière modification
		strftime(date, 20, "%Y-%m-%d %H:%M", gmtime(&fileStat.st_mtime));
		printf("%s ", date);
		
		// nom du fichier et saut de ligne
		printf("%s\n", file->d_name);
	}
	
	// si une erreur s'est produite sur "readdir"
	if(errno != 0) { perror("stat"); exit(errno); }
	
	return 0;
}

ok先到這,有時間繼續整理

發佈了73 篇原創文章 · 獲贊 101 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章