第一章:操作系統基本知識
1.根目錄下各個目錄的詳細介紹
/bin:二進制程序
/boot:啓動配置文件
/dev:設備文件 包含設備文件 終端設備,usb或連接到系統的任何設備
/etc:配置文件
/home:用戶家目錄
/lib:系統庫文件
/media:掛載可移動設備的臨時目錄
/mnt:掛載文件系統
/opt:提供一個可供選的應用
/proc:特殊的動態目錄,不同時間下,裏面的內容不一樣
/root:root用戶主目錄
/sbin:重要的系統二進制文件,通常由系統管理員使用
/sys:系統文件
/tmp:臨時文件
/usr:絕大多數用戶能訪問的應用程序
/var:經常變化的文件,如日誌或數據庫等
2.編寫函數,用strerror函數實現perror函數的功能。
先簡單介紹一下strerror和perror
在linux下的c語言程序運行過程當中有一個整形的errno全局變量一直存在,它的值即爲程序運行的錯誤碼的值.
將errno的值傳入strerror中,即可得到錯誤碼對應的錯誤名稱.
而perror則是將傳入自身的字符串最先打印,後面將錯誤名稱打印.
//通過標準錯誤的標號,獲得錯誤的描述字符串 ,將單純的錯誤標號轉爲字符串描述,方便用戶查找錯誤。
char * strerror(int errnum);
//簡單的說:就是errno轉爲錯誤字符串。
void perror(const char *s);
//將上一個函數的出錯信息輸出到標準設備。
//參數s所指的字符串先打印,後面跟上錯誤原因字符串。
答案如下:
void myperror(char * str)
{
extern int errno;
char *error=strerror(errno);
printf("%s: %s\n",str,error);
}
第二章:文件與目錄管理
1.什麼是文件描述符?什麼是流?二者有什麼區別和聯繫?
文件描述符是一個非負整數,它是文件進行輸入輸出的一個索引
流是對輸入輸出設備的抽象,具有方向性
同:1 都是程序和被操作文件之間連接,並可以在此基礎上進行讀着操作
2 都能和普通文件,設備文件等連接,用戶打開一個文件,要不返回一個文件描述符,要不返回一個流
3 都包含了很多庫函數
異:文件描述符是個整數,流是一個指向結構體的指針
2.用creat、open、close等系統調用,實現fopen、fclose的功能
3.設計一個程序,要求打開文件“pass”,如果沒有這個文件,新建此文件;讀取系統文件“etc/passwd”,把文件中的內容都寫入“pass”文件。
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd1, fd2;
char buf[1024];
fd1=open("pass",O_CREAT|O_RDWR|O_TRUNC,0666);
assert(fd1 > 0);
fd2=open("/etc/passwd", O_RDONLY);
int len;
while((len = read(fd2, buf, 1024)) > 0)
{
write(fd1, buf, len);
}
close(fd1);
close(fd2);
}
4.填空
- 在Linux中,所有設備和磁盤文件的打開操作都可使用 open 系統調用來進行。
- 調用 creat 函數可以創建一個文件,調用 stat 函數可以獲取文件的屬性。
- 在Linux中,文件的權限分爲 own、group 和 other 三類,每類分爲 可讀 ,可寫 ,可執行 權限。
- 讀取一個目錄文件的內容時,可使用系統調用 opendir 。
- 若file文件存取權限爲- r – x r- - - - -,這表明屬主有 可讀 權限,組用戶有 可執行 權限,其他用戶有 可執行 權限。
第三章:進程管理
1
- 在Linux中,進程的控制塊是一個名爲 task_struct 的結構體。
- 在Linux環境下,進程的兩種運行模式爲 用戶模式 和 root模式 。
- 在Linux的用戶空間中,創建一個新進程的方法是由某個已經存在的進程調用 fork 或 vfork 函數,被創建的新進程稱爲 子進程 ,已存在的進程稱爲 父進程 。
- 就緒態的進程是一個只需要 CPU 資源即可運行的進程。
- 進程結束時可以調用exit、_exit、abort三個函數,其中 abort 屬於異常結束進程的方法。
- 某進程調用wait函數後,如果該進程沒有子進程,則該進程將 立即返回結束 。
- 產生殭屍進程的要素是:子進程退出 、 父進程沒有回收內存資源 ;產生孤兒進程的要素是:父進程先與子進程退出,子進程被init進程收養 。
- 調用fork函數後在父進程中返回 子進程pid,在子進程中返回 0或負值(出錯)。
2.列出你的系統中當前所有正在運行的守護進程,簡要說明其功能。
apmd:高級電源治理
Arpwatch:記錄日誌並構建一個在LAN接口上看到的以太網地址和ip地址對數據庫
Autofs:自動安裝治理進程automount,與NFS相關,依靠於NIS
Bootparamd:引導參數服務器,爲LAN上的無盤工作站提供引導所需的相關信息
crond:linux下的計劃任務
Dhcpd:啓動一個DHCP(動態IP地址分配)服務器
Gated:網關路由守候進程,使用動態的OSPF路由選擇協議
Httpd:WEB服務器
Inetd:支持多種網絡服務的核心守候程序
3.編寫一個程序,程序中創建一個子進程用來打開你的Linux系統中的瀏覽器;父進程等待子進程結束後輸出子進程的退出值。
#include <stdio.h>
#include<stdlib.h>
#include<wait.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
int mian(int argc,char argv[])
{
pid_ t pid; .
int pid_ wait,status;
if((pid=fork())<0){
perror("fork");
exit(1);
}
else if(pid==O){
execle("/usr/bin/google-chrome ,google-chrome,NULL);
}
else{
pid_ wait=wait(&status);
if(WIFEXITED(status)){
printf("%d)n" ,WEXITSTATUS(status));
}
}
return 0;
}
第四章:管道與重定向
1
-
命令who 1>usrlist表示 輸出 重定向。
-
dup 和dup2函數可以用來複制文件描述符。
-
>>符號表示 追加 重定向。
-
編程將標準輸出重定向到文件描述符爲6對應的文件上,則應使用語句 dup2(6,1)。
-
管道就是將前一個命令的 輸出端 作爲後一個命令的 輸入端,分爲 有名管道 和 無名管道 兩種,其中 無名管道 只能在有親緣關係的進程間使用。
-
命名管道也稱爲FIFO文件。
-
使用pipe函數創建了匿名管道pfd,其中pfd[ 0 ]爲管道的讀端,pfd[ 1 ]爲管道的寫端。
2.請說明匿名管道和命名管道的異同點
異:1.匿名管道是由pipe函數創建 並打開的
命名管道是由mkfifo函數創建 的 ,打開用open
2. 匿名管道只能用於有親緣關係的進程之間的通信,而命名管道則可以用於任意兩個進程間的通信。
3. 匿名管道的生存依附於所在進程,命名管道的生存則不依附進程
同:1.都可以由read,write進行讀寫
2. 數據在這兩者中都遵循FIFO原則
3.通過管道模擬實現Shell命令:cat file | sort。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
int fd[2];
pid_t pid;
int start_val;
if(pipe(fd))
{
printf("pipe error!\n");
exit(1);
}
pid=fork();
switch(pid)
{
case -1:
printf("fork error!\n");
exit(1);
case 0:
close(0);
close(fd[1]);
dup(fd[0]);
printf("child program!\n");
execlp("sort","sort",NULL);
exit(0);
default:
close(1);
close(fd[0]);
dup(fd[1]);
printf("parent program!\n");
execlp("cat","cat","file.txt",NULL);
wait(&start_val);
exit(0);
}
return 0;
}
第五章:信號
1
-
在實際應用中,一個用戶進程常常需要對多個信號做出處理。爲了方便對多個信號進行處理,在Linux系統中引入 信號集 的概念。
-
進程可以忽略大部分信號,除了 SIGSTOP 和 SIGKILL 信號。
-
在kill(pid,signum)函數中,pid>0表示 將信號傳給進程識別碼爲 pid 的進程 。
-
Ctrl+\發送一個 SIGQUIT 信號。
-
SIGHUP信號的作用是 發送一個連接斷開信號 ,SIGCONT信號的作用是 讓一個停止的進程繼續執行 。
2有哪些事件或情況會產生信號?
1.當用戶按某些終端鍵時,將產生信號。
終端上按“Ctrl+c”組合鍵通常產生中斷信號 SIGINT,終端上按“Ctrl+\”鍵通常產生中斷信號 SIGQUIT,終端上按“Ctrl+z”鍵通常產生中斷信號 SIGSTOP 等。
2.硬件異常將產生信號。
比如數據運算時,除數爲0;或者無效的存放訪問等.這些條件通常由硬件檢測到,並通知內核,然後內核爲該條件發生時正在運行的進程產生適當的信號.。
3.軟件異常將產生信號。
當檢測到某種軟件條件已發生,並將其通知有關進程時,產生信號。
4.調用 kill() 函數將發送信號。
注意:接收信號進程和發送信號進程的所有者必須相同,或發送信號進程的所有者必須是超級用戶。
5.運行 kill 命令將發送信號。
此程序實際上是使用 kill 函數來發送信號。也常用此命令終止一個失控的後臺進程。
3.爲什麼說信號機制是一種異步通信方式?
因爲程序在運行的過程中並不知道將會發生什麼,因此進程不會去等某個事情發生,而是一直執行自己的事情,當發生一些特定的事件的時候,比如鍵盤ctrl+c的時候,我們會發送一個信號給進程,此時進程收到了信號,從而執行對信號的處理。因此信號機制是一種異步通信。
4.爲SIGUSR1信號安裝一個處理函數,當捕捉到該信號時,顯示當前的系統時間。用raise發送信號測試是否成功。
void func()
{
time_t timep;
time (&timep);
printf(“%s”,asctime(gmtime(&timep)));
}
void main()
{
signal(SIGUSR1,&func);
raise()
}
Linux操作系統編程課程期末試卷
1.在UNIX/Linux系統中,可以認爲操作系統用了三張表來描述一個打開的文件,請問是哪三張表,這三張表各自描述了文件的哪些屬性,它們之間是如何聯繫起來的?
1.文件描述符表 文件表 索引節點表
2.文件描述符表: 文件描述符標誌,指向一個文件表項的指針
文件表: 文件狀態標誌,文件讀寫偏移量,指向該文件索引節點表項的指針.
索引節點表: 文件屬性,數據塊位置,當前文件長度
3.通過指針指向對應表項
2.在UNIX/Linux系統中/etc/shadow文件用來存儲用戶密碼。所有用戶都可以通過執行passwd命令( /usr/bin/passwd)修改自己的密碼(修改/etc/shadow文件),但非root的其他用戶對/etc/shadow文件沒有讀寫權限,如下圖所示:
passwd命令的文件權限如下圖所示:
請闡述爲什麼所有用戶都可以通過執行passwd命令修改自己的密碼(修改/etc/shadow文件)?
passwd這個命令設置了s(setuid)權限,當一個可以執行程序具有setuid權限,用戶執行這個程序時,將以這個程序所有着身份執行。而passwd的擁有者是root用戶,因此普通用戶雖然沒有讀寫/etc/shadow文件的權限但是可以修改自己的密碼。