--- tags: sp講義 --- # sp筆記 # ch01-Linux的安裝與操作 >反正就是一些背景介紹,好無聊的 考試前再看個ppt應該就行 ![](https://i.imgur.com/UBhKZZR.png) Linux市佔率高所以要使用(Andriod也是) ## 伺服器版本vs桌面版 伺服器:文字(為了不容易當機) 桌面版:圖形化介面 ## 一些安裝 # ch01-安裝開發環境 繼續安裝 # ch02.1,gcc與gdb,github, man, gcc及優化選項, gdb ## github簡單介紹 https://mropengate.blogspot.com/2015/04/git-github.html ## vi vim <mark>這個一定要會</mark> **文字模式編輯器** **vim**:vi進階版(多了顏色) **Emacs**:跟vi差不多功能 簡單來說就是用來直接寫程式碼的 醬就不用下載寫完再上傳了 ## 文字介面 圖形化介面 ![](https://i.imgur.com/cRxNO4b.png) ## linux內建說明書 ![](https://i.imgur.com/UfU2UOn.png) ### man >指令的使用手冊 **man 3 printf**(c用的printf介紹) 3:代表第三本書(共9本) ![](https://i.imgur.com/uOy8rSi.png) **man 2 fork** ![](https://i.imgur.com/pdByjmE.png) **man -f**:列出所有的使用手冊 ![](https://i.imgur.com/pO4S0d9.png) 告訴你在哪幾本書裡面可以找到 --- ## gcc與gdb ### **gcc:編譯** ![](https://i.imgur.com/PqEchz6.png) -O3容易出錯=>因為可能會幫你把看似沒什麼用的東東處理掉 ``` a=3; b=a; ``` 醬a就有可能被弄掉 -Os=>編譯出比較小的執行檔 ### 指標錯誤 ``` #include <stdio.h> #include <stdlib.h> int main(){ int *p; /*指標未給初始值*/ int ret; ret = scanf("%d", p); printf("ret = %d, %d",ret, *p); } ``` => gcc pointer.c -g -o pointer => gcc ./pointer <mark>(-o後面放執行檔的名字 -g開啟除錯功能)</mark> 出現Segmentation fault,代表是指標出錯 => bt ![](https://i.imgur.com/jQAjSA9.png) >main(#2) 呼叫 #1, #1呼叫#0 => up ![](https://i.imgur.com/cXElR0T.png) 每up一次會**往下**一層(因為os堆疊是由上往下長) ### **gdb:除錯** ![](https://i.imgur.com/3iUgUEN.png) <mark>**gdb -tui ./pointer**</mark> 同時呼叫出簡易圖型化界面 # ch02.2 make,gprofile,valgrind,perf ## make ![](https://i.imgur.com/kSDWybB.png) 當發現相依性(時間較新)(這裡是target跟後面兩個.o檔) =>執行下面一行 簡單來說就是你有重寫某個檔他才會重新編譯這個檔 ![](https://i.imgur.com/bJvNXLt.png) ex:make hello =>執行hello那行 ![](https://i.imgur.com/McXk8tX.png) make後面若沒有跟任何參數的話 就會make all ## gprofile >GNU C內建的效能衡量工具 (看執行時間之類的) ### 編譯 => gcc table.c -pg -o table => ./table => gprof -b table gmon.out (gmon.out:-pg產生的一些額外程式碼) ### time(不用gprofile) => gcc table.c -o table => time ./table real:程式執行真正花的時間(打下指令~程式執行結束) user:聽不太懂(好像是real*你有幾核心同時在跑) sys:作業系統核心花的時間(system) ## 使用gdb反組譯 >就會出現組合語言的程式碼 可以看他實際到底是怎麼執行的 => gdb ./table => disassemble main (main可替換成其他想對其做反組譯的對象的樣子嗎) ## valgrind >檢查記憶體的相關問題 >分析各個東東佔的時間、記憶體之類的 ### 安裝 => sudo apt install valgrind => sudo apt install kcachegrind (kcachegrind:圖形化界面) ### 編譯 => gcc -g table.c => valgrind --tool=callgrind ./a.out => kcachegrind callgrind.out.#### >檔名會叫callgrind.out.#### #:數字 可以先ls找到檔名再進行 他會幫你叫出一個超酷視窗 ![](https://i.imgur.com/Mev8t83.png) <mark>但其實結果(消耗的時間)並不精準</mark> <mark>但對記憶體檢查很有幫助</mark> >因為他會幫你重新編譯並在每個指令加上額外的檢查程式碼 ## gedit => gedit table.c => gedit table.c & 可以看他的程式碼(幫你打開) 有加&代表執行在background 醬這邊就不會被鎖住,可以繼續打其他指令 ## rm => rm table.c 刪除檔案 ## perf >![](https://i.imgur.com/acCLe5S.png) 使用perf可以觀看各個執行單元的使用情況 ### 安裝 => sudo apt install linux-tools-common 之後就打 => perf 看他要你安裝甚麼裝一裝就行 ### 介紹 http://wiki.csie.ncku.edu.tw/embedded/perf perf的底層分為二種,分別是 * hardware performance counter:硬體事件 * software events:軟體事件 我們要用的是hardware performance counter https://en.wikipedia.org/wiki/Hardware_performance_counter >透過這些counter可以了解軟體在CPU內執行的具體情形 ### sandy bridge >好像不太重要的樣子 好像是把資料先存進buffer讓網路看起來流暢 但醬會導致有延遲時間 ### perf指令 ![](https://i.imgur.com/IC4yvs5.png) => sudo perf top ![](https://i.imgur.com/iTsDlt5.png) 偵測每個指令花了多少的CPU cycles(不知道就看圈起來那裡) >這邊的cycle可替換為量測其他CPU的效能 p:精準(p越多越精準) ![](https://i.imgur.com/pFXiGw5.png) => sudo perf top -e branch-instructions (branch-instructions可替換為圖下面其他的(量測其他CPU的效能)) => perf list 老師介紹了裡面的東東我也是沒聽太懂 # ch02.3 使用clock_gettime >非常精準的量測時間的函數 >總之就是介紹clock_gettime ## -Wall => gcc -Wall... 提示型別轉換 這類型的任何問題都會回報 ## 圖形化介面 ### Geany >好像很受歡迎的樣子 ### Visual Studio Code =>-exec 指令 必須先打-exec後面再接linux指令才能跑 ### Clion >可試用1個月 相較於eclipse比較不吃記憶體 ### Eclipse # ch04.1 檔案輸入與輸出 ## 檔案在linux是什麼樣子 ![](https://i.imgur.com/0AeVkTX.png) ![](https://i.imgur.com/3sNJ9A8.png) 檔案指標會自動往後移動100bytes 空洞:可能檔案裏面這部分就是沒寫資料(邏輯上有佔空間但可能記憶體根本就沒有配空間給他) ![](https://i.imgur.com/hTPAkBr.png) 檔案系統支援file hole以避免浪費太多磁碟空間 ## ex:mycp 要include 很多東西喔 This is [an example][id] reference-style link. ![](https://i.imgur.com/VInLhnn.png) RDONLY:只讀 WRONLY:只寫 CREAT:若檔案不存在就創一個 後面兩個是權限的後面再說 ## open ![](https://i.imgur.com/Tyt6yak.png) <mark>open回傳當下可用的最小號碼</mark> stdout:os稍微優化 stderr:馬上做(os沒有優化空間) ![](https://i.imgur.com/hmCxuIc.png) mode:權限(owner, group, others) ![](https://i.imgur.com/1vEKSzI.png) ### 自學open => man 2 open ### open重要參數 ![](https://i.imgur.com/jJuOhtV.png) ## read ![](https://i.imgur.com/jpWMKAM.png) ## write ![](https://i.imgur.com/qSLK2sc.png) ## perror >印出比較詳細一點的錯誤訊息 ![](https://i.imgur.com/KA6sNOm.png) ## errno >error number ![](https://i.imgur.com/ov2leP8.png) ## close >把檔案關掉 >把檔案內資料清空並讓釋放的資源ㄟ...free之類的 >忘記close的話會浪費系統很多資源 => lsof - list open files 查看程式打開了哪些檔案與是否忘記關 ## 自我學習 ![](https://i.imgur.com/IqK7CCJ.png) 不知道在幹嘛 # ch04.2 lseek & file holes ## hole.c ![](https://i.imgur.com/TmIGjEB.png) SEEK_SET:從頭 SEEK_CUR:從目前檔案指標位置 SEEK_END(應該是不確定):從尾 ## lseek() >檔案指標 >不會動到i/o >描述檔案目前在第幾個byte做讀寫 >不會真的移動或讀寫(虛擬的) ![](https://i.imgur.com/ALzffTo.png) ### lseek的whence ![](https://i.imgur.com/UnehhHG.png) ![](https://i.imgur.com/BXT34BA.png) ## 進階版mycp.c ![](https://i.imgur.com/OKwTeMU.png) ## 小節 ![](https://i.imgur.com/q9D2BOt.png) # ch04.3 sync & fsync & fdatasync ![](https://i.imgur.com/p3jjIdW.png) meta-data: 例如:檔案的修改日期、檔案的大小、檔案的瀏覽日期等等,這些外加的資料都「附屬」於該檔案,因此稱之為meta-data <mark>我也沒聽太懂,要用的時候建議再回去看一下</mark> ## 三個比較的實際執行 還沒看 # ch04.4 鎖定檔案flock ## 良心鎖v.s.強制鎖 **良心鎖**:每個process要存取檔案時要自己呼叫lock鎖定此檔案,而若有人已lock此檔,則lock不會成功,直到前一個人unlock後才能繼續執行。 若前一人執行lock,但你不執行而直接存取檔案,是可行的。 =>只防乖乖lock的人無法同時存取檔案 **強制鎖**:若不執行lock而直接存取則會失敗,其他同良心鎖 ## flock-良心鎖(advisory locking) ## flock.c ![](https://i.imgur.com/Tn1vtEZ.png) **LOCK_SH**:share lock/read lock,允許兩人同時讀取資料 **LOCK_EX**:exclusive lock/write lock,一次只能一人讀取資料 **LOCK_UN**:unlock,解除鎖定 ## flock-強制鎖(mandatory locking) ### 預備動作 ![](https://i.imgur.com/5M44wDe.png) 三行順序不能調換 => sudo mount -oremount.mand / 不知道為什麼寫醬才能正確執行 <mark>上面都做完之後這個檔案就可以做強制鎖了!</mark> ## 小結 ![](https://i.imgur.com/ru6977g.png) # ch05 c標準輸出入函數庫與作業系統 ## 開檔、寫檔、讀檔 ![](https://i.imgur.com/ruqrSq5.png) **./tmp**:路徑名 **w**:開啟模式 ![](https://i.imgur.com/knQkcfT.png) ### fopen的mode參數 ![](https://i.imgur.com/qA4Hgx3.png) ### stdin,stdout,stderr ![](https://i.imgur.com/HvNgCm3.png) ### 自學:fileno >回傳fd,跟作業系統溝通時用到 ### fprintf ![](https://i.imgur.com/3ITsBr3.png) ![](https://i.imgur.com/nfaI7LS.png) ### 檔案位置 ![](https://i.imgur.com/nHcdjgN.png) ### 練習append+fseek ![](https://i.imgur.com/gcCmVBv.png) ## buffer >增加程式效能 1. c函數庫的buffer 2. os的buffer 3. 硬體(hardward)的buffer ### c函數庫的buffer >把東西合併一起傳遞 ![](https://i.imgur.com/YCrMDAI.png) ### 設定buffer的大小 ![](https://i.imgur.com/amgHuwV.png) 這些都可以用但先介紹setvbuf #### setvbuf ![](https://i.imgur.com/G6aDF0n.png) **unbuffered**:例:stderr寫進去馬上傳遞 **line buffered**:跟互動有關的,遇到換行符號才換 **fully buffered**:通常用在寫到檔案,滿了再傳比較有效率 範例程式: ![](https://i.imgur.com/bwu4VML.png) ## 讀寫檔案,及檔案結尾 ![](https://i.imgur.com/jQSQXll.png) ### errors及EOF ![](https://i.imgur.com/PDHUbpH.png) ### 範例 ![](https://i.imgur.com/11Z0ziB.png) ### 小結 1.使用stream雖然比較方便,速度也往往比較快,但要注意glibc如何管理buffer 2.較大的buffer速度比較快,但萬一系統斷電或當機,也要冒比較大的風險 ## 製造系統中唯一的檔案 >一個系統的唯一暫存檔 >每隔一段時間自動幫他暫存 ![](https://i.imgur.com/E6ptS4s.png) ### mktemp ![](https://i.imgur.com/WRMVuAn.png) ![](https://i.imgur.com/LsmbA26.png) ![](https://i.imgur.com/dY15T3l.png) 1.產生檔名 2.製造檔案 ### 小結 ![](https://i.imgur.com/xNy8lUj.png) ## 未介紹的部分 >對亞洲字元的支援 ### wchar.h ### uchar.h # ch06 ## ch06.1 檔案及目錄 ### ls -alh ![](https://i.imgur.com/PD6oNWZ.png) .開頭的都是隱藏檔,其他是普通檔案 r=>讀 w=>寫 x=>可否執行 l=>link捷徑 三組各自代表不同人所擁有的權限: 最前面那欄:一槓(-):檔案,d:目錄,l:link捷徑 -__1__-__2__-__3__- 第一組:owner 第二組:group 第三組:others 123那個是hard-link個數 中間那個是檔案大小(沒列h的話顯示的會是byte大小) ![](https://i.imgur.com/d1ChUaN.png) ![](https://i.imgur.com/Be0fZVh.png) ![](https://i.imgur.com/UKOZjmD.png) ![](https://i.imgur.com/9LS3kwr.png) ![](https://i.imgur.com/KPMf9yA.png) ## ch06.2 檔案的特殊屬性set-uid ![](https://i.imgur.com/ajmsuPp.png) >執行者:可讀自己的檔案 >檔案owner:執行時就不能看到自己的檔案了,只能看到該檔案owner的檔案 需要set-uid能在兩者之間切換 ![](https://i.imgur.com/rJKG006.png) >euid:執行者 >ruid:檔案owner 例外 ![](https://i.imgur.com/rzR7CIk.png) ### 應用:password ![](https://i.imgur.com/adlXJQB.png) ### 超級ls ![](https://i.imgur.com/5lg7Dga.png) ... ### sticky bit >現在已經沒有作用了,以前建在檔案上面,現在建在目錄上 ![](https://i.imgur.com/WXBDvUZ.png) ## ch06.3 硬連結及軟連結 ### hard link ![](https://i.imgur.com/etqnTlS.png) >只可連向檔案不可連向目錄為了避免迴圈 >要連目錄就用soft link >目前有兩個link指向這個檔案=>2 >hard link上只會有數字(檔案編號) ### soft link ![](https://i.imgur.com/Irt9UPO.png) >soft link不會影響數量(2),他只計hard link >partition就是根目錄裡的東東(c槽d槽那種) ### 硬碟的處理 ![](https://i.imgur.com/hP5RzUa.png) >unix裡面掛載的目錄數量可以無限多 >windows有限 ### 目錄系統、檔案系統 ![](https://i.imgur.com/UofZ14a.png) ![](https://i.imgur.com/R6F9a5x.png) >/etc/fstab:只有super user可改 #### unix中的file ![](https://i.imgur.com/T1kQV2s.png) #### soft link狀況 ![](https://i.imgur.com/ozItTYT.png) >要有從頭到該檔案路徑下所有檔案的存取權 >hard link就不用 >若file 6消失,link依然會指向同一個位置,直到真正存取時,作業系統才會發現soft link指向的是不存在的東東(若新建一個file 6,仍能存取這個新的file 6) ### 小結 ![](https://i.imgur.com/VKjsdnV.png) ## ch06.4操作目錄及檔案屬性 ### mkdir ![](https://i.imgur.com/I0yxAco.png) >umask:避免權限設定錯誤 ### rmdir ![](https://i.imgur.com/OU57vPW.png) >操作前還是要check權限的 ### chdir ![](https://i.imgur.com/MltXAeL.png) ### getcwd ![](https://i.imgur.com/QPv8fJi.png) >pwd回傳目前工作目錄的絕對路徑 >PATH_MAX:有可能不是常數!! 比起用malloc,可以用get_current_dir_name ![](https://i.imgur.com/tjiQZob.png) >直接分配夠大的buffer,回傳buffer address,用完要記得free掉 ## ch06.5 條列目錄裡所有的物件 ### ls ![](https://i.imgur.com/IFoK76y.png) > 目錄是搜尋樹,不是文字檔(但原本設定是文字檔) ### dirent >列出目錄中東東 ![](https://i.imgur.com/zMjEgGQ.png) #### dir ![](https://i.imgur.com/41Mavwz.png) #### listDir ![](https://i.imgur.com/ljQ2bHd.png) ![](https://i.imgur.com/jyJ3Oqz.png) ## ch06.6 利用stat讀取檔案屬性 >讀的屬性為inode的屬性(較完整) >更進階版的dir ![](https://i.imgur.com/3PDYeMY.png) ![](https://i.imgur.com/RBT0QcM.png) >st_blocks:佔據多少檔案大小 **atime:上次存取的時間 mtime:上次修改的時間 ctime:上次修改inode的時間(不能改,上面兩個其實都可以改)** > linux未提供函數修改ctime ![](https://i.imgur.com/jZEkTS1.png) >這邊的至少都一定要記得 ### dir2 ![](https://i.imgur.com/WTnxwJA.png) ![](https://i.imgur.com/ZJ1IdNF.png) ![](https://i.imgur.com/4ao2AmH.png) ![](https://i.imgur.com/ieb5tIC.png) ## ch06.7 檔案的操作 umask >最大權限 ![](https://i.imgur.com/VSbu8Lx.png) ![](https://i.imgur.com/vyJjf9X.png) ![](https://i.imgur.com/oaaFjMo.png) 以下都是umask的功能 ### unlink ![](https://i.imgur.com/ovTuKJw.png) ### rename ![](https://i.imgur.com/a2IfRno.png) ## ch06.8 設定檔案的ACL ![](https://i.imgur.com/o5mTot8.png) ![](https://i.imgur.com/JTAVpEV.png) > 這兩個是指令 > 理論上可以設置無限個使用者的讀取權限 > 實際上要看檔案配給ACL的空間大小 =>getfacl ![](https://i.imgur.com/EzDeBw9.png) =>setfacl ![](https://i.imgur.com/QoDTuk7.png) ![](https://i.imgur.com/45uytCJ.png) >user: :rw- 沒有特別寫那就是owner(預設的那個) >group的就是group mask:若有umask => mask會覆蓋掉umask的設定 ![](https://i.imgur.com/aGqXiPt.png) ### 小結 ![](https://i.imgur.com/h0OH0Ls.png) ## ch06.10 監聽檔案異動 > 也可以監聽目錄(特別的檔案) ### inotify ![](https://i.imgur.com/1oL34ss.png) ### 小結 ![](https://i.imgur.com/l0wTZG5.png)