Linux服務器開發一(基礎)

Linux

  • 一、Linux介紹
    • Linux是類Unix計算機操做系統的統稱。
    • Linux操做系統的內核的名字也是「Linux」。
    • Linux這個詞自己只表示Linux內核,但在實際上人們已經習慣了用Linux來形容整個基於Linux內核的系統。
    • Linux是由芬蘭大學Linus Torvalds於1991年編寫的。
  • 二、Linux發行版組成
    • Linux內核
    • 應用軟件
      • 一些GNU程序庫和工具
        • emacs
        • GCC
        • GNOME
      • 命令行shell
      • 圖形桌面環境
        • KDE(qt編寫)
        • GNOME(GTK編寫)
        • Unity
      • 一些辦公軟件
        • OpenOffice
      • 編譯器
        • gcc
        • g++
      • 文本編輯器到科學工具的應用軟件
        • vi
        • gedit
  • 三、Linux版本
    • 商業公司維護的發行版本
      • RedHat(REHL)包管理方式採用基於RPM包的YUM包管理方式
    • 社區組織維護的發行版本
      • Debian 包管理方式採用的是:apt-get/dpkg xxx.deb
    • RedHat系列
      • RHEL(RedHat Enterprice Linux, 也就是所謂的RedHat Advance Server收費版本),穩定。
      • CentOS(RHEL的社區克隆版本,免費),穩定。
      • FedoraCore(由原來的RedHat桌面版本發展而來,免費版本),穩定性差,最好只用於桌面應用。
    • Debian系列
      • Debian
      • Ubuntu
        • 命名規則
          • 前兩位數字:發行時的年份的最後兩位數字
          • 後兩位數字:發行的月份
        • 版本
          • 桌面版(Desktop):至少三年的技術支持
          • 服務器版(Server):至少五年的技術支持
          • LTS版本(Long Term Support)
        • 版本發佈頻率,一年兩次
          • 主版本號(年份)
            • 單數年:短時間支持版
            • 雙數年:長期支持版(LTS)
          • 副版本號(月份)
            • 四月份(xx.04):該年度的穩定版
            • 十月份(xx.10):該年度的測試版

學習方法

  • 要求
    • 記好課堂筆記
    • 只聽不練學不會Linux,多動手實踐
    • 課上跟上思路,簡單的命令跟着敲,多思考
    • 分清主次,重點記憶重要命令
  • 資料
    • Linux自帶幫助文檔 - man
    • 鳥哥和私房菜

1、文件和目錄操做

  • 一、基本的shell操做
    • shell命令行快捷鍵node

      • 編輯命令linux

        Ctrl + a          移到命令行首, ahead,與home鍵功能相同
          Ctrl + e          移到命令行尾, end, 與end鍵功能相同
          Ctrl + f          按字符前移(右向), forward, 與方向鍵left功能相同
          Ctrl + b          按字符後移(左向), back, 與方向鍵right功能相同
          Alt  + f          按單詞前移(右向)
          Alt  + b          按單詞後移(左向)
          Ctrl + xx         在命令行首和光標之間移動
          Ctrl + u          從光標處刪除至命令行首
          Ctrl + k          從光標處刪除至命令行尾
          Ctrl + w          從光標處刪除至字首
          Alt  + d          從光標處刪除至字尾
          Ctrl + d          刪除光標處的字符, 與delete鍵功能相同
          Ctrl + h          刪除光標前的字符, 與backspace鍵功能相同
          Ctrl + y          粘貼至光標後, yank
          Alt  + c          從光標處更改成首字母大寫的單詞
          Alt  + u          從光標處更改成所有大寫的單詞, uppercase
          Alt  + l          從光標處更改成所有小寫的單詞, lowercase
          Ctrl + t          交換光標處和以前的字符
          Alt  + t          交換光標處和以前的單詞
          Alt  + Backspace  與 Ctrl + w 相似,分隔符有些差異
      • 從新執行命令程序員

        Ctrl + r          逆向搜索命令歷史
          Ctrl + g          從歷史搜索模式退出
          Ctrl + p          歷史中的上一條命令, previous,與方向鍵up功能相同
          Ctrl + n          歷史中的下一條命令, next, 與方向鍵down功能相同
          Alt  + .          使用上一條命令的最後一個參數
      • 控制命令shell

        Ctrl + l          清屏, clear
          Ctrl + o          執行當前命令,並選擇上一條命令
          Ctrl + s          阻止屏幕輸出
          Ctrl + q          容許屏幕輸出
          Ctrl + c          終止命令
          Ctrl + z          掛起命令
      • Bang (!) 命令編程

        !!                執行上一條命令
          !blah             執行最近的以 blah 開頭的命令,如 !ls
          !blah:p           僅打印輸出,而不執行
          !$                上一條命令的最後一個參數,與 Alt + . 相同
          !$:p              打印輸出 !$ 的內容
          !*                上一條命令的全部參數
          !*:p              打印輸出 !* 的內容
          ^blah             刪除上一條命令中的 blah
          ^blah^foo         將上一條命令中的 blah 替換爲 foo
          ^blah^foo^        將上一條命令中全部的 blah 都替換爲 foo
    • 虛擬終端(VT)
      • 簡介ubuntu

        英文:Virtual Terminal
          解釋:鏈接在遠地的分時共用計算機系統的遠程終端,它具備使用戶感到是在計算機旁使用終端的功能。
      • 經常使用工具vim

        XManager
          Putty
          SecureCRT
    • 命令和路徑補齊windows

      tab鍵按一次    當只有一個匹配時,自動補全命令或路徑
        tab鍵按兩次    當有多個匹配時,顯示命令或路徑列表
  • 二、Linux 標準目錄結構緩存

    初學Linux,首先須要弄清Linux 標準目錄結構:bash

    /
          root --- 啓動Linux時使用的一些核心文件。如操做系統內核、引導程序Grub等。
          home --- 存儲普通用戶的我的文件
              ftp --- 用戶全部服務
              httpd
              samba
              user1
              user2
          bin --- 系統啓動時須要的執行文件(二進制)
          sbin --- 可執行程序的目錄,但大多存放涉及系統管理的命令。只有root權限才能執行
          proc --- 虛擬,存在linux內核鏡像;保存全部內核參數以及系統配置信息
              1 --- 進程編號
          usr --- 用戶目錄,存放用戶級的文件
              bin --- 幾乎全部用戶所用命令,另外存在與/bin,/usr/local/bin
              sbin --- 系統管理員命令,與用戶相關,例如,大部分服務器程序
              include --- 存放C/C++頭文件的目錄
              lib --- 固定的程序數據
              local --- 本地安裝軟件保存位置
              man --- 手工生成的目錄
              info --- 信息文檔
              doc --- 不一樣包文檔信息
              tmp
              X11R6 ---  該目錄用於保存運行X-Window所需的全部文件。該目錄中還包含用於運行GUI要的配置文件和二進制文件。
              X386 --- 功能同X11R6,X11 發行版5 的系統文件
          boot --- 引導加載器所需文件,系統所需圖片保存於此
          lib --- 根文件系統目錄下程序和核心模塊的公共庫
              modules --- 可加載模塊,系統崩潰後重啓所需模塊
          dev --- 設備文件目錄
          etc --- 配置文件
              skel --- home目錄創建,該目錄初始化
              sysconfig --- 網絡,時間,鍵盤等配置目錄
          var
              file
              lib --- 該目錄下的文件在系統運行時,會改變
              local --- 安裝在/usr/local的程序數據,變化的
              lock --- 文件使用特定外設或文件,爲其上鎖,其餘文件暫時不能訪問
              log --- 記錄日誌
              run --- 系統運行合法信息
              spool --- 打印機、郵件、代理服務器等假脫機目錄
              tmp
              catman --- 緩存目錄
          mnt --- 臨時用於掛載文件系統的地方。通常狀況下這個目錄是空的。
                  在咱們將要掛載分區時在這個目錄下創建目錄,再將咱們將要訪問的設備掛載在這個目錄上,這樣咱們就可訪問文件了。
          tmp --- 臨時文件目錄,系統啓動後的臨時文件存放在/var/tmp
          lost+found --- 在文件系統修復時恢復的文件

    /

    根目錄,通常根目錄下只存放目錄,不要存放文件。
          /etc、/bin、/dev、/lib、/sbin應該和根目錄放置在一個分區中。

    /bin, /usr/bin

    可執行二進制文件的目錄,如經常使用的命令ls、tar、mv、cat等。

    /boot

    放置linux系統啓動時用到的一些文件。/boot/vmlinuz爲linux的內核文件,以及/boot/gurb。建議單獨分區,分區大小100M便可。

    /dev

    存放linux系統下的設備文件,訪問該目錄下某個文件,至關於訪問某個設備,經常使用的是掛載光驅mount:
          /dev/cdrom、/mnt

    /etc

    系統配置文件存放的目錄,不建議在此目錄下存放可執行文件。
          重要的配置文件有:/etc/inittab、/etc/fstab、/etc/init.d、/etc/X十一、/etc/sysconfig、/etc/xinetd.d。
          修改配置文件以前記得備份。
    
          注:/etc/X11存放與x windows有關的設置。

    /home

    系統默認的用戶家目錄,新增用戶帳號時,用戶的家目錄都存放在此目錄下。
          ~表示當前用戶的家目錄,~test表示用戶test的家目錄。
          建議單獨分區,並設置較大的磁盤空間,方便用戶存放數據。

    /lib,/usr/lib,/usr/local/lib

    系統使用的函數庫的目錄,程序在執行過程當中,須要調用一些額外的參數時須要函數庫的協助,比較重要的目錄爲/lib/modules。

    /lost+fount

    系統異常產生錯誤時,會將一些遺失的片斷放置於此目錄下,一般這個目錄會自動出如今裝置目錄下。
          如加載硬盤於/disk 中,此目錄下就會自動產生目錄/disk/lost+found

    /mnt,/media

    光盤默認掛載點,一般光盤掛載於/mnt/cdrom下,也不必定,能夠選擇任意位置進行掛載。

    /opt

    給主機額外安裝軟件所擺放的目錄。
          如:FC4使用的Fedora 社羣開發軟件,若是想要自行安裝新的KDE 桌面軟件,能夠將該軟件安裝在該目錄下。
          之前的 Linux 系統中,習慣放置在 /usr/local 目錄下。

    /proc

    此目錄的數據都在內存中,如系統核心,外部設備,網絡狀態,因爲數據都存放於內存中,因此不佔用磁盤空間。
          比較重要的目錄有/proc/cpuinfo、/proc/interrupts、/proc/dma、/proc/ioports、/proc/net/*等。

    /root

    系統管理員root的家目錄,系統第一個啓動的分區爲/,因此最好將/root和/放置在一個分區下。

    /sbin,/usr/sbin,/usr/local/sbin

    放置系統管理員使用的可執行命令,如fdisk、shutdown、mount等。
          與/bin不一樣的是,這幾個目錄是給系統管理員root使用的命令,通常用戶只能"查看"而不能設置和使用。

    /tmp

    通常用戶或正在執行的程序臨時存放文件的目錄,任何人均可以訪問,重要數據不可放置在此目錄下。

    /srv

    服務啓動以後須要訪問的數據目錄,如www服務須要訪問的網頁數據存放在/srv/www內。

    /usr

    應用程序存放目錄。
          /usr/bin 存放應用程序。
          /usr/share 存放共享數據。
          /usr/lib 存放不能直接運行的,倒是許多程序運行所必需的一些函數庫文件。
          /usr/local 存放軟件升級包。
          /usr/share/doc 系統說明文件存放目錄。
          /usr/share/man 程序說明文件存放目錄。
          使用 man ls時會查詢/usr/share/man/man1/ls.1.gz的內容。
          建議單獨分區,設置較大的磁盤空間。

    /var

    放置系統執行過程當中常常變化的文件。
          /var/log 隨時更改的日誌文件。
          /var/log/message 全部的登陸文件存放目錄。
          /var/spool/mail 郵件存放的目錄。
          /var/run 程序或服務啓動後,其PID存放在該目錄下。
          建議單獨分區,設置較大的磁盤空間。
  • 三、文件和目錄操做相關命令
    • 用戶目錄
      • 絕對路徑:從根目錄開始寫,如/usr/bin
      • 相對路徑:相對於當前的工做目錄而言
        • . 當前目錄
        • .. 當前目錄的上一級目錄
        • - 在臨近的兩個目錄直接切換
      • root@ubuntu:~#
        • root: 當前用戶名
        • @:at, 在
        • ubuntu:主機名
        • ~ : 當前用戶home目錄
        • #:超級用戶
        • $:普通用戶
    • ls

      ls -al
            -a, --all           不隱藏任何以. 開始的項目
            -l                  使用較長格式列出信息
      
        -rw-r--r--  1 super root     3771 6月   7  2016 .bashrc
        drwx------ 22 super root     4096 12月 15 08:02 .cache
        lrwxrwxrwx  1 super root       31 11月 23 07:42 .vimrc -> /home/super/.spf13-vim-3/.vimrc
      
        以最後一個爲例:
        lrwxrwxrwx
        第1個字符:表示文件類型
            -   普通文件
            d   目錄
            l   連接符號
            b   塊設備
            c   字符設備
            s   socket文件
            p   管道
        第2-4個字符:文檔全部者權限
        第5-7個字符:同組用戶權限
        第8-10個字符:其餘人權限
        r: read 4
        w: write 2
        x: execute 1
      
        1               文件的硬連接數
        super           該文件或目錄的全部者
        root            該文件或目錄所屬的組
        31              佔用的存儲空間
        11月 23 07:42   文件最後建立或修改的時間
        .vimrc          文件名
    • cd

      cd ~        切換到用戶home目錄
        cd /        切換到根目錄
        cd          切換到用戶home目錄
        cd..        切換到上一級目錄
    • tree

      tree path   顯示指定路徑的目錄樹結構
    • 文件或目錄顏色通常狀況

      白色          普通文件
        藍色          目錄
        綠色          可執行文件
        紅色          壓縮文件
        青色          連接文件
        黃色          設備文件
        灰色          其餘文件
    • mkdir

      mkdir dirname               建立目錄。
        mkdir dir1/dir2/dir3 -p     按層次建立目錄。
    • rmdir

      rmdir dirname       目錄必須爲空才能刪除,因此實際使用時不經常使用。
    • rm

      rm -rf dirname      遞歸強制刪除文件夾下的目錄和文件,實際使用中經常使用。
        rm -ri dirname      遞歸刪除並提示用戶刪除了哪些目錄或文件。
    • touch

      touch test.txt      建立文件。
    • cp

      cp hello.c temp     在當前目錄下生成一個temp文件,並把hello.c的內容寫入文件。
                            若是temp不存在,則建立文件;若是存在,則覆蓋已有文件。
      
        cp mydir newdir -r  在當前目錄下生成一個newdir目錄,並把mydir目錄裏面的目錄或文件拷貝過去。
                            若是目錄不存在,則建立;若是存在,則mydir目錄自己也拷貝到newdir目錄下。
    • cat

      cat test.txt        查看文件的內容,缺點內容太多時查看困難。
    • more

      more stdio.h        分屏查看文件,Enter下翻一行,Space下翻一頁,缺點不能往回看。
    • less

      less stdio.h        分屏查看文件。比more更實用,能夠來回翻頁。
                            ctrl + p    上翻一行
                            ctrl + n    下翻一行
                            ctrl + b    上翻一頁
                            ctrl + f    下翻一頁
                            q           退出
    • head

      head -5 stdio.h     查看前五行內容,不加參數默認是10行。
    • tail

      tail -5 stdio.h     查看後5行內容, 不加參數默認是10行。
    • mv

      mv test.c hello.c   移動到。多用於重命名目錄或文件。
    • ln

      ln -s ~/.vim/.vimrc .vimrc      建立軟連接,至關於windows下的快捷方式,可用於目錄或文件。
                                        路徑要用絕對路徑,這樣軟連接拷貝到哪裏都是有效的。
                                        若是刪除原文件,則軟連接失效。
      
        ln .vimrc .vimrc.hard           建立硬連接,只能用於文件。沒必要使用絕對路徑。
                                        建立後生成的硬連接與原文件引用同一個inode,硬連接自己不佔硬盤空間。
                                        若是刪除原文件,硬連接仍然有效。
    • wc

      wc test.c       統計文件的行數,字數,字節數。
    • od

      od -tx test.c       以十六進制形式查看文件。
        od -tc test.c       以ASCII字符形式查看文件。
        od -td test.c       以有符號十進制形式查看文件。
        od -tf test.c       以浮點數形式查看文件。
        od -to test.c       以八進制形式查看文件。
        od -tu test.c       以無符號十進制形式查看文件。
    • du

      du -h       查看當前文件夾下的目錄或文件所佔用磁盤的大小。
    • df

      df -h       查看當前文件夾下的目錄或文件所使用磁盤空間的詳細狀況。
    • which

      which ls    查看外部命令的位置,內部命令沒法查看。
    • pwd

      pwd         查看當前所在目錄
  • 四、文件權限、用戶、用戶組相關命令
    • 查看當前用戶

      whoami      查看當前用戶名。
        id          查看當前用戶信息,如用戶名,所屬羣組,UID,GID等。
    • 修改目錄或文件權限
      • 文字設定法

        chmod [who] [+|-|=] [mode]
          who : 不指定的話,默認是全部
              文件全部者:u
              文件所屬組:g
              其餘人:o
              全部人:a
          mode
              r : 讀
              w : 寫
              x : 執行
          chmod o+w temp      給其餘人加寫權限。
          chmod a-x temp      給全部人去除執行權限。
          chmod a=r temp      全部人只有讀權限。
      • 數字設定法

        -   0   沒有權限
          r   4   讀
          w   2   寫
          x   1   執行
        
          chmod 755 temp      -rwxr-xr-x
          chmod -001 temp     -rwxr-xr--
    • 修改目錄或文件全部者與所屬組

      chown root temp         把文件temp的全部者修改成root。
        chown super:root temp   把文件temp的全部者修改super,所屬組修改成root。
    • 修改目錄或文件所屬組

      chgrp root temp         修改文件所屬組爲root。
    • 目錄必須有執行權限,不然不能打開目錄。

  • 五、查找和檢索相關命令
    • 按文件屬性查找
      • 文件名

        find ~ -name "hello.c"      按完整名稱匹配
          find ~ -name "*.h"          *表明任意長度字符
          find ~ -name "tem?"         ?表明一個任意字符
      • 文件大小

        find ~ -size +10k               查找大於10k的文件
          find ~ -size -10M               查找小於10M的文件
          find ~ -size +10M -size -100M   查找大於10M小因而100M的文件
      • 文件類型

        find ~ -type p      查找類型爲管道的檔案
          find ~ -type f      查找類型爲文件的檔案
          find ~ -type d      查找類型爲目錄的檔案
          find ~ -type l      查找類型爲連接的檔案
    • 按文件內容查找

      grep -r "stdio.h" ~     在用戶家目錄中查找文件內容裏包括stdio.h的全部文件
  • 六、軟件安裝和卸載
    • 在線安裝
      • apt-get

        安裝      apt-get install tree        在線下載安裝
          移除      apt-get remove tree
          更新      apt-get update              更新軟件列表
          清理      apt-get clean               清理全部軟件安裝包,實際上清理的是/var/cache/apt/archives目錄下的.deb文件
      • aptitude

        安裝       aptitude install tree
          從新安裝    aptitude reinstall tree
          更新       apt-get update
          移除       aptitude remove tree
          顯示狀態    aptitude show tree
    • deb包安裝
      • 安裝

        dpkg -i xxx.deb
      • 刪除

        dpkg -r xxx
    • 源碼安裝

      1)解壓縮源代碼包。
        2)進入安裝目錄。
        3)檢測文件是否缺失,建立Makefile,檢測編譯環境:./configure。
        4)編譯源碼,生成庫和可執行程序:make。
        5)把庫和可執行程序,安裝到系統目錄下:make install。
        6)刪除和卸載軟件:make distclean。
        7)上述安裝步驟並非絕對的,應該先查看附帶的README文件。
  • 七、磁盤管理
    • 磁盤設備種類

      hd      Hard Disk         硬盤
        fd      Floppy Disk       軟盤
        sd      SCSI Device       小型計算機系統接口(英語:Small Computer System Interface; 簡寫:SCSI)。
                                  一種用於計算機和智能設備之間(硬盤、軟驅、光驅、打印機、掃描儀等)系統級接口的獨立處理器標準。
                                  SCSI是一種智能的通用接口標準。
        設備都保存在/dev中
    • sd後面加小寫字母,分別表明不一樣的硬盤,如:

      sda     第一個硬盤
        sdb     第二個硬盤
        sdc     第三個硬盤
        sdd     第四個硬盤
    • 每一個硬盤又分爲主分區和邏輯分區,一個硬盤最多容許四個主分區,第一個邏輯分區從sda5開始。

      主分區:
        sda1    主分區1
        sda2    主分區2
        sda3    主分區3
        sda4    主分區4
      
        擴展分區:
        sda5    邏輯分區1
        sda6    邏輯分區2
        sda7    邏輯分區3
        ......
    • 查看設備信息

      fdisk -l    當你不知道usb的名稱時,能夠用這個命令在獲取
    • 掛載USB

      mount /dev/sdb1 /mnt
        注: 若是掛載的目錄不是一個空目錄,則目錄裏面的內容會被臨時覆蓋掉,致使目錄原有文件沒法操做,卸載後會恢復原有文件。
        建議使用空目錄, 如/mnt。
    • 卸載USB

      umount /mnt

2、打包壓縮和經常使用服務器

  • 一、壓縮包管理
    • 屌絲版
      • gzip -- .gz格式壓縮包

        gzip *.txt      假設當前目錄中有a.txt和b.txt, 則會生成a.txt.gz和b.txt.gz,txt源文件會被刪除。
                          這個命令不能用於目錄。
          gunzip *.gz     解壓
      • bzip2 -- .bz2格式的壓縮包

        bzip2 -k *.txt  假設當前目錄中有a.txt和b.txt,則會生成a.txt.bz2和b.txt.bz2文件,加-k參數能夠將源文件保留。
                          這個命令不能用於目錄。
          bunzip2 *.bz2   解壓
    • 高富帥版
      • tar -- 不使用z或j參數,該命令只能對文件和目錄打包
        • 參數

          c       建立--壓縮時使用。
            x       釋放--解壓縮時使用。
            v       顯示提示信息--壓縮和解壓縮均可以使用,能夠省略。
            f       指定壓縮文件的名字
          
            z       使用gzip的方式壓縮文件
            j       使用bzip2的方式壓縮文件
        • 壓縮

          用法:tar zcvf 生成的壓縮包的名字(xxx.tar.gz) 要壓縮的文件或目錄
            示例:tar zcvf alltxt.tar.gz *.txt test/       同時對文件和目錄進行打包壓縮
          
            用法:tar jcvf 生成的壓縮包的名字(xxx.tar.bz2) 要壓縮的文件或目錄
            示例:tar jcvf alltxt.tar.bz2 *.txt test/      同時對文件和目錄進行打包壓縮
        • 解壓縮

          tar zxvf 壓縮包的名字                 解壓到當前目錄
            tar jxvf 壓縮包的名字 -C 目錄           解壓到指定目錄
      • rar
        • 參數

          a       Add壓縮
            x       Extract解壓縮
            r       壓縮時遞歸目錄,不加這個參數默認就是遞歸的
        • 壓縮

          用法:rar a 生成的壓縮文件的名字 壓縮的文件或目錄
          
            示例:
            rar a all *.txt         打包壓縮文件
            rar a dir dir/          打包壓縮目錄
        • 解壓縮

          用法:rar x 壓縮文件名 [解壓縮目錄]
            示例:rar x all.rar
      • zip
        • 參數

          r       壓縮目錄時加個參數用於遞歸目錄,不加不能壓縮
        • 壓縮

          用法:zip 壓縮包的名字 壓縮的文件或目錄
            示例:zip all *.txt
                 zip -r myzip mytest/
        • 解壓縮

          用法:unzip 壓縮包的名字
               unzip 壓縮包的名字 -d 解壓的目錄
            示例:unzip all.zip
                 unzip all.zip -d test/
  • 二、進程管理
    • 查看在線用戶狀態

      who                 查看當前在線用戶的狀態
      
        tty1~tty6           文字界面終端
        tty7                圖形界面終端
        pts                 虛擬終端
        Alt+Ctrl+F1~F7      切換終端,切換後各個終端互不影響
    • 查看進程

      ps aux                  查看在線用戶下全部進程
        ps aux | grep bash      進程過濾
    • 終止進程

      kill -l                 查看全部信號
        kill -SIGKILL 5179      終止進程
        kill -9 4678            終止進程
    • 查看當前進程的環境變量

      env                     查看全部環境變量
        env | grep PATH         只查看PATH環境變量
    • 查看系統狀態

      top
  • 三、網絡管理
    • 獲取網絡接口信息

      ifconfig
    • 測試與目標主機連通性

      ping www.baidu.com -c 4     發送4個數據包後終止
    • 查看服務器域名對應的IP地址

      nslookup www.baidu.com
  • 四、用戶管理
    • 建立用戶

      adduser super       用戶名只能小寫,不能大寫
        useradd -s /bin/bash -g super -d /home/super -m super       用戶名能夠大寫
        -s      指定新用戶登錄時shell類型
        -g      指定所屬組,該組必須已經存在
        -d      用戶家目錄
        -m      用戶家目錄不存在時,自動建立該目錄
    • 設置用戶組

      groupadd super
    • 刪除用戶

      deluser super
        userdel -r super        選項-r的做用是把用戶的主目錄一塊兒刪除
    • 切換用戶

      su super
    • 修改用戶密碼

      passwd super
    • 退出當前用戶

      exit
    • 查看全部用戶信息

      vi /etc/passwd
  • 五、ftp服務器搭建
    • vsftpd做用:文件的上傳和下載
    • 服務器端
      • 安裝vsftpd

        apt-get install -y vsftpd       安裝完成後會隨系統啓動而自動啓動
      • 修改配置文件

        vi /etc/vsftpd.conf
        
          listen=YES
          anon_root=/home/super/anonFtp/      #指定匿名用戶根目錄,不指定默認是/srv/ftp/
          anonymous_enable=YES    #容許匿名用戶登陸
          write_enable=YES        #實名用戶擁有寫權限(上傳數據)
          local_umask=022         #設置本地掩碼爲022
          anon_upload_enable=YES      #匿名用戶能夠向ftp服務器上傳數據
          anon_mkdir_write_enable=YES     #匿名用戶能夠在ftp服務器上建立目錄
      • 建立匿名用戶根目錄

        cd ~
          mkdir anonFtp
          chown ftp anonFtp
          chmod 777 anonFtp
      • 重啓服務

        service vsftpd retart
    • 客戶端
      • 實名用戶登陸

        ftp IP(server)
          輸入用戶名
          輸入密碼
        
          文件的上傳和下載
              文件的上傳: put file
              文件的下載: get file
              不容許操做目錄,若是想操做目錄 -- 打包tar/rar/zip
      • 匿名用戶登陸

        ftp IP(server)
          用戶名:anonymous
          密碼:直接回車
        
          不容許匿名用戶在任意目錄直接切換
          只能在一個指定目錄範圍內工做
          須要在ftp服務器上建立一個匿名用戶的目錄 -- 匿名用戶的根目錄
      • 退出

        quit        推薦
          bye         推薦
          exit
    • lftp客戶端訪問ftp服務器

      • 一個ftp客戶端工具,能夠上傳和下載目錄
      • 安裝

        apt-get install -y lftp
      • 登陸服務器
        • 匿名

          lftp IP(sever) 回車
            login
        • 實名

          lftp username@IP(sever) 回車
            輸入服務器密碼
      • 操做

        put file                上傳文件
          mput file1 file2        上傳多個文件
          get file                下載文件
          mget file1 file2        下載多個文件
          mirror dir              下載整個目錄及其子目錄
          mirror -R dir           上傳整個目錄及其子目錄
  • 六、nfs服務器搭建
    • net file system : 網絡文件系統,它容許網絡中的計算機之間經過TCP/IP網絡共享資源。
    • 服務器端
      • 安裝

        apt-get install nfs-kernel-server       安裝成功後會隨系統啓動而自動啓動
      • 建立共享目錄

        如: /home/super/NfsShare
      • 修改配置文件

        vi /etc/exports
          在文件最後加入下面設置:
          /home/super/NfsShare *(rw, sync)
      • 重啓服務

        service nfs-kernel-server restart
    • 客戶端
      • 掛載服務器共享目錄

        用法: mount serverIP:ShareDir /mnt
          示例: mount 192.168.10.100:/home/super/NfsShare /mnt
  • 七、ssh(Secure Shell)服務器
    • 服務器端
      • 安裝ssh

        apt-get install -y openssh-server
          aptitude show openssh-server
    • 客戶端
      • 遠程登陸

        ssh Username@ServerIP
      • 退出登陸

        logout
  • 八、scp(Super Copy)命令
    • 使用該命令的前提條件

      目標主機已經安裝了openssh-server
    • 使用方法

      scp -r 目標用戶名@目標主機IP地址:/目標文件的絕對路徑 /保存到本機的絕對(相對)路徑
        scp -r super@192.168.10.100:/home/super/SCP/ ./mydir/
  • 九、其餘命令
    • 翻頁

      Shift+PageUp        上翻頁
        Shift+PageDown      下翻頁
    • 清屏

      clear
        Ctrl+l
    • 建立終端

      Ctrl+Alt+T      Ubuntu
        Ctrl+Shift+T    添加新標籤頁
    • 看手冊

      man man
      
        一共有九個章節,1,2,3,5是重點:
        1   可執行程序或 shell 命令
        2   系統調用(內核提供的函數)
        3   庫調用(程序庫中的函數)
        4   特殊文件(一般位於 /dev)
        5   文件格式和規範,如 /etc/passwd
        6   遊戲
        7   雜項(包括宏包和規範,如man(7),groff(7))
        8   系統管理命令(一般只針對root用戶)
        9   內核例程 [非標準
    • 設置查看別名

      alias                   查看
        alias l='ls -al'        設置
    • 在顯示器上顯示數據

      echo "hello"    打印字符串
        echo $PATH      打印環境變量
        echo $?         顯示上一次程序退出值
  • 十、關機重啓
    • poweroff
    • reboot
    • shutdown
      • 參數

        -t      秒數:設定在切換至不一樣的runlevel以前,警告和刪除兩訊號之間的延遲時間(秒)
          -k      僅送出警告訊息文字,但不是真的要shutdown
          -r      shutdown以後從新開機
          -h      shutdown以後關機
          -n      不通過init,由shutdown指令自己來作關機動做(不建議使用)
          -f      從新開機時,跳過fsck指令,不檢查檔案系統
          -F      從新開機時,強迫作fsck檢查
          -c      將已經正在shutdown的動做取消
      • 示例

        shutdown -r now     #當即重啓
          shutdown -h now     #當即關機
          shutdown -k now 'Hey! Go away! now...'      #發出警訊息,但沒有真的關機
          shutdown -t3 -r now     #當即重啓,但在警告和刪除processes之間,延遲3秒鐘
          shutdown -h 10:42 'Hey! Go away!'   #10:42關機
          shutdown -r 10 'Hey! Go away!'      #10分鐘後關機
          shutdown -c     #取消shutdown指令,必須切換至其餘tty,登入以後,才能下些命令
          shutdown now    #切換至單人操做模式(不加任何選項時)

3、vim和函數庫

一、vim編輯器的使用

1.一、vim簡介

  • Vim是從 vi 發展出來的一個文本編輯器。代碼補全、編譯及錯誤跳轉等方便編程的功能特別豐富,在程序員中被普遍使用,和Emacs並列成爲類Unix系統用戶最喜歡的文本編輯器。

1.二、工做模式

  • 命令模式 -- 打開文件以後,默認進入命令模式。
    • 移動光標

      h           左
        j           下
        k           下
        l           右
        0           行首
        $           行尾
        gg          文件頭部
        G           文件尾部
        5G          行跳轉,移到第五行
    • 刪除操做(不是真正意義上的刪除,更象是剪切操做)

      x           刪除光標後一個字符
        X           刪除光標前一個字符
        dw          刪除光標後一個單詞
        d0          刪除光標到行首的全部字符
        D(d$)       刪除光標到行尾的全部字符
        dd          刪除一行
        5dd         刪除五行
    • 撤消操做

      u           撤消
        ctrl+r      還原前一個操做
    • 複製粘貼

      p           小寫的p,粘貼到光標的下一行
        P           大寫的p,粘貼到光標的所在行
        yy          複製一行
        5yy         複製五行
    • 可視模式

      v           切換到可視塊模式
        h/j/k/l     調整選中塊
        y           複製
        d           刪除
        p           粘貼
    • 查找模式

      /           切換到查找模式,向下查找
        ?           切換到查找模式,向上查找
        n           下一個匹配
        N           上一個匹配
        #           移到要查找的單詞上,按#號便可開啓查找模式
    • 字符替換

      r           單個字符替換
    • 行縮進

      >>          向右縮進
        <<          向左縮進
    • 查看函數man文檔

      K           先輸入3(庫函數章節),再輸入K,以查看指定函數的man文檔
  • 編輯模式 -- 須要輸入一些命令,切換到編輯模式。

    a       在光標所在位置的後邊插入
      A       在當前行的尾部插入
    
      i       在光標所在位置的前邊插入
      I       在光標所在行的行首插入
    
      o       在光標所在行的下邊開闢一個新的行
      O       在光標所在行的上邊開闢一個新的行
    
      s       刪除光標後邊的字符
      S       刪除光標全部的行
  • 末行模式 -- 在末行模式下能夠輸入一些命令。

    :s/tom/jack/g           把光標所在行的tom替換成jack
      :%s/tom/jack/g          把整個文檔的tom替換成jack
      :25,30s/tom/jack/g      把25到30行的tom替換成jack
    
      :q          退出
      :q!         強制退出
      :w          保存
      :wq         保存並退出
      :x          至關於:wq
      ZZ          至關於:wq
  • 分屏操做

    :sp [file]      將屏幕水平分紅兩部分
      :vsp [file]     交屏幕垂直分紅兩部分
      :wqall          同時保存打開文件
      ctrl+ww         切換兩個屏幕
  • vim打形成IDE

    /etc/vim/vimrc      系統級配置文件
      ~/.vim/vimrc        用戶級配置文件

二、gcc編譯器

  • gcc編譯的四個階段:

    hello.c  -------->   hello.i  -------->    hello.s  -------->    hello.o  ------->    hello.out
              預處理編譯器(cpp)     編譯器(gcc)          彙編器(as)           連接器(ld)
              gcc -E                gcc -S                gcc -c                gcc
  • 編譯工具鏈:

    預處理編譯器:cpp     gcc -E hello.c -o hello.i   頭文件展開,宏替換,註釋去掉
                   編譯器:gcc     gcc -S hello.i -o hello.s   c文件變成彙編文件
                   彙編器:as      gcc -c hello.s -o hello.o   彙編文件變成二進制文件
                   連接器:ld      gcc hello.o -o hello        將函數庫中相應的代碼組合到目標文件中
  • 直接編譯生成可執行文件

    gcc hello.c -o hello
  • 編譯時指定頭文件目錄-I

    gcc hello.c -I ./include hello
  • 編譯時指定宏,一般用於調試代碼-D

    gcc hello.c -D DEBUG
    
      在須要打印日誌的代碼中加上下面的語句:
      #ifdef DEBUG
          printf("debug info");
      #endif
  • 編譯時對代碼進行優化-O3

    gcc hello.c -o hello -O3 
      級別:
      0   沒有優化
      1   缺省值
      3   優化級別最高
  • 編譯時顯示告警信息-Wall

    gcc hello.c -o hello -Wall
  • 編譯時包含調試信息-g(gdb)

    gcc hello.c -o hello -g
  • 查看編譯版本

    gcc -v
      gcc --version

三、靜態庫的建立和使用

  • 準備

    目錄結構
      myCalc
      ├── include
      │   └── head.h
      ├── lib
      │   └── libMyCalc.a
      ├── main.c
      └── src
          ├── add.c
          ├── div.c
          ├── mul.c
          ├── sub.c
  • 命名格式
    • lib開頭。
    • 靜態庫名。
    • .a結尾。

      示例 : libMyCalc.a
  • 描述
    • 優勢
      • 尋址方便、速度快。
      • 庫被打包到可執行程序中,直接發佈可執行程序便可使用。
    • 缺點
      • 靜態庫的代碼在編譯過程當中已經被載入可執行程序,所以體積較大。
      • 若是靜態函數庫改變了,那麼你的程序就必須從新編譯。
    • 使用場合
      • 在覈心程序上使用,保證速度,忽略空間。
      • 主流應用於80、90年代,如今不多使用。
  • 製做
    • 獲得與位置有關的*.o

      cd ~/myClac/src
        gcc *.c -c -I ../include
    • 將生成的*.o文件打包成靜態庫libMyCalc.a

      ar rcs libMyCalc.a *.o
      
        ar工具不包含在一gcc中。
        參數:
        r       將文件夾插入到靜態庫中。
        c       建立靜態庫,無論庫是否存在。
        s       寫入一個目標文件索引到庫中,或者更新一個存在的目標文件。
      
        製做好之後移動到lib目錄中
        mv libMyCalc.a ../lib
    • 查看庫中的符號(函數)

      nm libMyCalc.a
    • 發佈和使用靜態庫
      • 發佈靜態庫,把includelib目錄打包給用戶。
      • 使用
        • main.c中包含頭文件

          #inlcude "head.h"
        • 兩種編譯方式

          gcc main.c lib/libMyCalc.a -I include -o myapp
            gcc main.c -I include -L lib -l MyCalc -o myapp
        • 執行myapp

          ./myapp

四、動態庫的建立和使用

  • 準備

    目錄結構
      myCalc
      ├── include
      │   └── head.h
      ├── lib
      │   └── libMyCalc.so
      ├── main.c
      └── src
          ├── add.c
          ├── div.c
          ├── mul.c
          ├── sub.c
  • 命名格式
    • lib開頭。
    • 靜態庫名。
    • .so結尾。

      示例 : libMyCalc.so
  • 描述
    • 優勢
      • 執行程序體積小。
      • 動態庫更新了,不須要從新編譯程序,前提是函數接口不變。
    • 缺點
      • 發佈程序的時候,須要將動態庫提供給用戶。
      • 動態庫沒有被打包到應用程序中,加載速度相對較慢。
    • 使用場合
      • 現代應用程序中經常使用。
  • 製做
    • 生成與位置無關的*.o

      cd ~/myClac/src
        gcc -fPIC *.c -c -I ../include
    • 將生成的*.o文件打包成共享庫(動態庫)libMyCalc.so

      gcc -shared -o libMyCalc.so *.o -I ../include
      
        製做好之後移動到lib目錄中
        mv libMyCalc.so ../lib
    • 查看庫中的符號(函數)

      nm libMyCalc.so
    • 發佈和使用靜態庫
      • 發佈靜態庫,把includelib目錄打包給用戶。
      • 使用
        • main.c中包含頭文件

          #inlcude "head.h"
        • 兩種編譯方式

          gcc main.c lib/libMyCalc.so -I include -o myapp
            gcc main.c -I include -L lib -l MyCalc -o myapp
        • 執行myapp

          ./myapp
        • 查看可執行文件夾所依賴的動態庫

          ldd myapp
        • 解決依賴的動態庫沒法加載的問題
          • libMyCalc.so拷貝到/lib目錄下(不推薦使用,容易與系統庫衝突)

            cp lib/libMyCalc.so /lib
          • 設置環境變量LD_LIBRARY_PATH(測試時使用)

            export LD_LIBRARY_PATH=./lib    只對當前會話有效
          • 設置環境變量LD_LIBRARY_PATH到~/.bashrc中(測試時使用)

            vi ~/.bashrc
              export LD_LIBRARY_PATH=/home/super/myCalc/lib       會話每次開啓就會生效
          • 設置配置文件/etc/ld.so.conf(推薦使用),重啓終端
            • 編輯動態鏈接器的配置文件

              vi /etc/ld.so.conf
            • 動態庫的路徑寫到配置文件中

              /home/super/myCalc/lib
            • 更新動態庫

              ldconfig -v

4、makefile和文件IO

一、gdb調試

  • 1.一、啓動gdb

    gdb app
  • 1.二、查看代碼

    >>>(gdb) l          #list
      >>>(gdb) l 行號或函數名
      >>>(gdb) l 文件名:行號或函數名
  • 1.三、設置斷點
    • 設置當前文件斷點

      >>>(gdb) b      #break
        >>>(gdb) b 行號或函數名
        >>>(gdb) b 文件名:行號或函數名
    • 設置條件斷點

      >>>(gdb) b 10 if value==19
    • 刪除斷點

      >>>(gdb) d 斷點的編號        #delete或del
  • 1.四、查看設置的斷點

    >>>(gdb) i b            #info, 能夠獲取斷點的編號,刪除斷點時用
  • 1.五、開始執行gdb調試

    >>>(gdb) start      #只執行一步
      >>>(gdb) c          #continue,直接停在斷點的位置
      >>>(gdb) run        #有斷點會停在斷點處,沒有會直接跑完程序,較少用
  • 1.六、單步調試

    >>>(gdb) s          #進入函數體內部
      >>>(gdb) finish     #從函數體內部跳出
      >>>(gdb) n          #不進入函數體內部
      >>>(gdb) u          #退出當前循環
  • 1.七、查看變量的值

    >>>(gdb) p      print
  • 1.八、查看變量的類型

    >>>(gdb) ptype 變量名
  • 1.九、設置變量的值

    >>>(gdb) set var 變量=值
  • 1.十、設置追蹤變量

    >>>(gdb) display 變量        #設置追蹤變量
      >>>(gdb) info display        #獲取變量的編號
      >>>(gdb) undisplay 編號       #取消追蹤變量
  • 1.十、退出gdb調試

    >>>(gdb) quit

二、makefile的編寫

2.一、makefile的命名

makefile
    Makefile

    注:兩種任選其中一種,其餘名稱不行。

2.二、makefile的規則

  • 規則中的三要素:目標、依賴、命令
    • makefile文件內容格式

      目標:依賴文件
            命令
    • makefile文件內容簡單示例

      app:main.c add.c sub.c mul.c div.c
            gcc main.c add.c sub.c mul.c div.c -o app
    • 第二行必須有一個tab縮進。

  • 子目標和終極目標
    • 示例

      #終極目標
        app:main.o add.o sub.o div.o
            gcc main.o add.o sub.o div.o -o app
        #子目標
        main.o:main.c
            gcc -c main.c
        #子目標
        add.o:add.c
            gcc -c add.c
        #子目標
        sub.o:sub.c
            gcc -c sub.c
        #子目標
        mul.o:mul.c
            gcc -c mul.c
        #子目標
        div.o:div.c
            gcc -c div.c
    • 好處
      • 當其餘一個文件被修改時,只會編譯修改的文件,再打包生成app,編譯效率高。
  • 更新目標的原則

2.三、makefile的兩個函數

  • wildcard:取得目錄下的全部文件
  • patsubst:將目標下的全部文件做替換
  • 示例

    #自定義變量
      src=$(wildcard ./*.c)
      obj=$(patsubst ./%.c, ./%.o, $(src))
      target=app
      #終極目標
      $(target):$(obj)
          gcc $(obj) -o $(target)
      #子目標
      %.o:%.c
          gcc -c $< -o $@

2.四、makefile的三個自動變量

  • 普通變量
    • 變量取值:foo = $(obj)
    • 由makefile維護的一些變量
      • 一般格式都是大寫
        • CC: 默認值是cc
      • 有些有默認值,有些沒有
        • CPPFLAGS: 預處理器須要的選項,如:-I
        • CFLAGS: 編譯的時候使用的參數 -Wall -g -c
        • LDFLAGS: 連接庫使用的選項 -L -l
      • 用戶能夠修改這些變量的默認值
        • CC = gcc
  • 自動變量
    • 變量
      • $< 規則中的第一個依賴條件
      • $@ 規則中的目標
      • $^ 規則中的全部依賴條件
      • 以上三種變量只能在規則的命令中使用
    • 模式規則
      • 在規則的目標定義中使用%
      • 在規則的依賴條件中使用%
      • 示例

        #自定義變量
          src=$(wildcard ./*.c)
          obj=$(patsubst ./%.c, ./%.o, $(src))
          target=app
          #makefile維護的變量
          CC = gcc
          CPPFLAGS = -I
          #終極目標
          $(target):$(obj)
              $(CC) $^ -o $@
          #子目標
          %.o:%.c
              $(CC) -c $< -o $@
          #僞目標
          .PHONY:clean
          clean:
              #命令前面加-表示,若是命令執行失敗則忽略這個命令
              -makir /release
              rm -f $(obj) $(target)

三、系統IO函數

3.一、一些概念

  • C庫IO函數工做流程
    C庫IO函數工做流程

  • 虛擬內存地址空間
    虛擬內存地址空間

  • pcb與文件描述符
    pcb與文件描述符

  • 庫函數與系統函數之間的關係
    庫函數與系統函數之間的關係

  • CPU爲何要使用虛擬地址空間與物理地址空間映射?解決了什麼問題?
    • 方便編譯器和操做系統安排程序的地址分佈。
      • 程序可使用一系列相鄰的虛擬地址來訪問物理內存中不相鄰的大內存緩衝區
    • 方便進程之間隔離
      • 不一樣進程使用的虛擬地址彼此隔離,一個進程中的代碼沒法更改正在由另外一個進程使用的物理內存。
    • 方便OS使用你那可憐的內存
      • 程序可使用一系列虛擬地址來訪問大於可用物理內存的內存緩衝區。當物理內存的供應量變小時,內存管理器會將物理內存頁(一般大小爲4KB)保存到磁盤文件。數據或代碼頁會根據須要在物理內存和磁盤之間移動。
  • 查看幫助文檔

    man 2 open
      man 3 printf
  • errno
    • 定義在頭文件/usr/include/error.h
      • 全局變量
      • 任何標準C庫函數都能對其進行修改(Linux系統函數更能夠)
  • 錯誤宏定義位置
    • 第1-34個錯誤定義:/usr/include/asm-generic/errno-base.h
    • 第35-133個錯誤定義:/usr/include/asm-generic/errno.h
  • 是記錄系統的最後一次錯誤代碼。代碼是一個int型的值。
    • 第個errno值對應着以字符串表示的錯誤類型。
    • 當調用「某些」函數出錯時,該函數會從新設置errno的值。
  • perror函數
    • 頭文件stdio.h
    • 函數定義void perror(const char * s)
    • 函數說明
      • 用來將上一個函數發生的錯誤的緣由輸出到標準設備(stderr)。
      • 參數s所指的字符串會先打印出,後面再加上錯誤緣由字符串。
      • 些錯誤緣由依照全局變量error的值來決定要輸出的字符串。

3.二、open

  • 函數定義

    int open(const char *pathname, int flags);
      int open(const char *pathname, int flags, mode_t mode);
  • 功能

    打開文件。
  • 參數

    pathname    文件路徑,如./hello.c
      flags       文件訪問模式,O_RDONLY, O_WRONLY, O_RDWR, 更多見man 2 open
      mode        文件權限設置,實際結果是mode & umask
  • 返回值

    返回一個文件描述fd,-1表示打開文件時發生錯誤。
  • 示例

    #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
      #include <unistd.h>
      #include <stdlib.h>
      #include <stdio.h>
    
      int main()
      {
          int fd; 
          //打開文件
          fd = open("hello.c", O_RDWR);
          //打開文件,不存在則建立並設置權限爲:755 & umask
          fd = open("hello.c", O_RDWR | O_CREAT, 0755);
          //打開文件,不存在則建立並設置權限爲:755 & umask,另判斷文件是否存在
          fd = open("hello.c", O_RDWR | O_CREAT | O_EXCL, 0755);
          //打開文件並清空文件裏的內容
          fd = open("hello.c", O_RDWR | O_TRUNC);
    
          printf("fd = %d\n", fd);
          //打開失敗則打印錯誤並退出程序
          if(fd == -1) 
          {   
              perror("open file failure");
              exit(1);
          }   
    
          int ret = close(fd);
          printf("ret = %d\n", ret);
          //關閉失敗則打印錯誤並退出程序
          if(ret == -1) 
          {   
              perror("close file failure");
              exit(1);
          }   
          return 0;
      }

3.三、read

  • 函數定義

    ssize_t read(int fd, void *buf, size_t count);
  • 功能

    讀取文件。
  • 參數

    fd          文件描述符
      buf         緩衝區
      count       讀取多少字節數
  • 返回值

    有符號int型值
      -1      表示讀文件失敗
      0       表示文件讀完了
      >0      表示讀取的字節數

3.四、write

  • 函數定義

    ssize_t write(int fd, const void *buf, size_t count);
  • 功能

    寫入文件。
  • 參數

    fd          文件描述符
      buf         緩衝區
      count       讀取多少字節數
  • 返回值

    有符號int型值
      -1      表示寫文件失敗
      0       表示什麼都沒寫
      >0      表示寫了多少字節數
  • 示例

    #include <stdio.h>
      #include <stdlib.h>
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
      #include <unistd.h>
    
      int main()
      {
          //以只讀方式找開文件
          int fd = open("english.txt", O_RDONLY);
          if(fd == -1)
          {
              perror("open");
              exit(1);
          }
          //以寫的方式找開文件,文件不存在則建立
          int fd1 = open("newfile", O_CREAT | O_WRONLY, 0664);
          //打開失敗,打印錯誤並退出程序
          if(fd1 == -1)
          {
              perror("open1");
              exit(1);
          }
    
          char buf[2048] = {0};
          //每次讀取2048字節
          int count = read(fd, buf, sizeof(buf));
          //讀取失敗,打印錯誤並退出程序
          if(count == -1)
          {
              perror("read");
              exit(1);
          }
          while(count)
          {
              //寫入文件
              int ret = write(fd1, buf, count);
              printf("write bytes %d\n", ret);
              //繼續讀取內容
              count = read(fd, buf, sizeof(buf));
          }
          //關閉文件
          close(fd);
          close(fd1);
          return 0;
      }

3.五、close

  • 函數定義

    int close(int fd);
  • 功能

    關閉文件。
  • 參數

    fd      文件描述符
  • 返回值

    0       表示關閉成功
      -1      表示關閉失敗

3.六、lseek

  • 函數定義

    off_t lseek(int fd, off_t offset, int whence);
  • 功能

    一、獲取文件大小。
      二、移動文件指針。
      三、文件拓展。
  • 參數

    fd          文件描述符
      offset      文件指針偏移量
      whence      來源,主要值有:SEEK_SET、SEEK_CUR、SEEK_END等
  • 返回值

    有符號int型值
      -1      表示讀文件失敗
      0       表示文件讀完了
      >0      表示讀取的字節數
  • 示例

    #include <unistd.h>
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
      #include <stdio.h>
      #include <stdlib.h>
    
      int main()
      {
          int fd = open("aa", O_RDWR);
          if(fd == -1)
          {
              perror("open file");
              exit(1);
          }
    
          int ret = lseek(fd, 0, SEEK_END);
          printf("file length = %d\n", ret);
    
          //文件拓展
          ret = lseek(fd, 2000, SEEK_END);
          printf("return value = %d\n", ret);
    
          //實現文件拓展,須要再最後作一次寫操做
          write(fd, "a", 1);
    
          close(fd);
          return 0;
      }

5、一些系統函數的使用

一、Linux文件操做相關函數

stat函數

  • 函數定義

    int stat(const char *pathname, struct stat *buf);
  • 功能

    獲取文件屬性(從inode上獲取)。
  • 參數

    pathname        文件名
      buf             結構體指針stat
  • 返回值

    0       成功
      -1      失敗
  • 文件屬性

    struct stat 
      {
             dev_t     st_dev;         /* 文件的設備編號 */
             ino_t     st_ino;         /* 節點 */
             mode_t    st_mode;        /* 文件的類型和存取的權限 */
             nlink_t   st_nlink;       /* 連接到該文件的硬連接數目,剛創建的文件值爲1 */
             uid_t     st_uid;         /* 用戶ID */
             gid_t     st_gid;         /* 組ID */
             dev_t     st_rdev;        /* (設備類型)若此文件爲設備文件,則爲其設備編號 */
             off_t     st_size;        /* 文件字節數(文件大小) */
             blksize_t st_blksize;     /* 塊大小(文件系統的I/O, 緩衝區的大小) */
             blkcnt_t  st_blocks;      /* 塊數 */
             struct timespec st_atim;  /* 最後一次訪問時間 */
             struct timespec st_mtim;  /* 最後一次修改時間 */
             struct timespec st_ctim;  /* 最後一次改變時間(屬性) */
      }
  • 特性
    • 可以穿透(跟蹤)符號連接。若是是軟連接,會統計原始文件信息,而不是軟連接的信息。
  • 示例

    #include <sys/types.h>
      #include <sys/stat.h>
      #include <stdlib.h>
      #include <time.h>
      #include <pwd.h>
      #include <grp.h>
    
      int main(int argc, char * argv[])
      {
          if(argc < 2)
          {
              printf("./a.out filename\n");
              exit(1);
          }
    
          struct stat st;
          int ret = stat(argv[1], &st);
          if(ret == -1)
          {
              perror("stat");
              exit(1);
          }
          //存儲文件類型和訪問權限
          char perms[11] = {0};
          //判斷文件類型
          switch(st.st_mode & S_IFMT)
          {
              case S_IFLNK:
                  perms[0] = 'l';
                  break;
              case S_IFDIR:
                  perms[0] = 'd';
                  break;
              case S_IFREG:
                  perms[0] = '-';
                  break;
              case S_IFBLK:
                  perms[0] = 'b';
                  break;
              case S_IFCHR:
                  perms[0] = 'c';
                  break;
              case S_IFSOCK:
                  perms[0] = 's';
                  break;
              case S_IFIFO:
                  perms[0] = 'p';
                  break;
              default:
                  perms[0] = '?';
                  break;                
          }
    
          //判斷文件的訪問權限
          //文件全部者
          perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-';
          perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-';
          perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-';
          //文件所屬組
          perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-';
          perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-';
          perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-';
          //其餘人
          perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-';
          perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-';
          perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';
    
          //硬連接計數
          int linkNum = st.st_nlink;
          //文件全部者
          char * fileUser = getpwuid(st.st_uid)->pw_name;
          //文件所屬組
          char * fileGrp = getgrgid(st.st_gid)->gr_name;
          //文件大小
          int filesize = (int)st.st_size;
          //修改時間
          char * time = ctime(&st.st_mtime);
          char mtime[512] = {0};
          strncpy(mtime, time, strlen(time) - 1);
    
          char buf[1024];
          sprintf(buf, "%s %d %s %s %d %s %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]);
    
          printf("%s\n", buf);
    
          return 0;
      }
  • st_mode
    • 該變量佔兩字節,共16位。
    • 掩碼的使用:st_mode & 掩碼
    • 其餘人權限(0-2 bit)

      S_IROTH 00004 讀權限
        S_IWOTH 00002 寫權限
        S_IXOTH 00001 執行權限
        S_IRWXO 00007 掩碼
    • 所屬組權限(3-5 bit)

      S_IRGRP 00040 讀權限
        S_IWGRP 00020 寫權限
        S_IXGRP 00010 執行權限
        S_IRWXG 00070 掩碼
    • 文件全部者權限(6-8 bit)

      S_IRUSR 00400 讀權限
        S_IWUSR 00200 寫權限
        S_IXUSR 00100 執行權限
        S_IRWXU 00700 掩碼
    • 特殊權限位(9-11 bit),不多用

      S_ISUID 0004000 設置用戶ID
        S_ISGID 0002000 設置組ID
        S_ISVTX 0001000 黏住位
    • 文件類型(12-15 bit)

      S_IFSOCK 0140000 套接字
        S_IFLNK 0120000 符號連接(軟連接)
        S_IFREG 0100000 普通文件
        S_IFBLK 0060000 塊設備
        S_IFDIR 0040000 目錄
        S_IFCHR 0020000 字符設備
        S_IFIFO 0010000 管道
        S_IFMT 0170000 掩碼

st_mode

lstat函數

  • 功能和用法與stat相同
  • 特性:不穿透(跟蹤)符號連接。若是是軟連接,會統計軟連接的信息,而不是原始文件的信息。
  • 連接的追蹤
    連接的追蹤

access函數

  • 函數定義

    int access(const char *pathname, int mode);
  • 功能

    測試指定文件是否擁有某種權限。
  • 參數

    pathname        文件名
      mode            權限類別
                      R_OK        是否有讀權限
                      W_OK        是否有寫權限
                      X_OK        是否有執行權限
                      F_OK        測試一個文件是否存在
  • 返回值

    0       全部欲查覈的權限都經過了檢查
      -1      有權限被禁止
  • 示例

    #include <stdio.h>
      #include <stdlib.h>
      #include <unistd.h>
    
      int main(int argc, char * argv[])
      {
          if(argc < 2)
          {
              printf("access filename\n");
              exit(1);
          }
    
          int ret = access(argv[1], W_OK);
          if(ret == -1)
          {
              perror("access");
              exit(1);
          }
          printf("you can write this file.\n");
          return 0;
      }

chmod函數

  • 函數定義

    int chmod(const char *pathname, mode_t mode);
  • 功能

    改變文件的權限
  • 參數

    pathname        文件名
      mode            權限,必須是一個8進制數字,轉換用strtol函數
  • 返回值

    0       改變成功
      -1      失敗
  • 示例

    #include <stdio.h>
      #include <stdlib.h>
      #include <sys/stat.h>
    
      int main(int argc, char * argv[])
      {
          if(argc < 2)
          {
              printf("chmod filename\n");
              exit(1);
          }
    
          int ret = chmod(argv[1], 0755);
          if(ret == -1)
          {
              perror("chmod");
              exit(1);
          }
          return 0;
      }

chown函數

  • 函數定義

    int chown(const char *pathname, uid_t owner, gid_t group);
  • 功能

    改變文件的全部者
  • 參數

    pathname        文件名
      owner           文件全部者ID
      group           文件所屬組ID
    
      查看UID和GID:/etc/passwd
  • 返回值

    0       成功
      -1      失敗
  • 示例

    #include <stdio.h>
      #include <stdlib.h>
      #include <unistd.h>
    
      int main(int argc, char * argv[])
      {
          if(argc < 2)
          {
              printf("chown filename\n");
              exit(1);
          }
    
          int ret = chown(argv[1], 116, 125);
          if(ret == -1)
          {
              perror("chown");
              exit(1);
          }
          return 0;
      }

truncate函數

  • 函數定義

    int truncate(const char *path, off_t length);
  • 功能

    將參數path指定的文件大小改成參數length指定的大小。若是原來的文件大小比參數length大,則超過部分會被刪去。
  • 參數

    path        文件路徑
      length      指定文件的大小
  • 返回值

    0       成功
      -1      失敗

鏈接函數

  • link函數
    • 函數定義

      int link(const char *oldpath, const char *newpath);
    • 功能

      建立一個硬連接。
  • symlink函數
    • 函數定義

      int symlink(const char *target, const char *linkpath);
    • 功能

      建立一個軟連接。
  • readlink函數
    • 函數定義

      ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
    • 功能

      讀軟連接對應的文件名,而不是讀內容。
    • 示例

      #include <stdio.h>
        #include <stdlib.h>
        #include <unistd.h>
      
        int main(int argc, char * argv[])
        {
            if(argc < 2)
            {
                printf("readlink filename\n");
                exit(1);
            }
      
            char buf[512];
            int ret = readlink(argv[1], buf, sizeof(buf));
            if(ret == -1)
            {
                perror("readlink");
                exit(1);
            }
            buf[ret] = 0;
            printf("buf = %s\n", buf);
      
            return 0;
        }
  • unlink函數
    • 函數定義

      int unlink(const char *pathname);
    • 功能

      刪除一個文件的目錄並減小它的連接數,若成功則返回0,不然返回-1,錯誤緣由存於errno。
        若是想調用這個函數來成功刪除文件,你就必須擁有這個文件的所屬目錄的寫和執行權限。
    • 使用

      若是是符號連接,刪除符號連接。
        若是是硬連接,硬連接數減1,,當減爲0時,釋放數據塊和inode。
        若是文件硬連接數爲0,但有進程已打開該文件,並持有文件描述符,則等該進程關閉該文件時,kernel才真正去刪除該文件。
    • 示例

      #include <stdio.h>
        #include <stdlib.h>
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <unistd.h>
        #include <fcntl.h>
      
        int main()
        {
            int fd = open("tempfile", O_CREAT | O_RDWR, 0664);
            if(fd == -1)
            {
                perror("open");
                exit(1);
            }
            //刪除臨時文件
            int ret = unlink("tempfile");
      
            //write file
            write(fd, "hello\n", 5);
      
            //重置文件指針
            lssek(fd, 0, SEEK_SET);
      
            //read file
            char buf[24] = {0};
            int len = read(fd, buf, sizeof(buf));
      
            //將讀出的內容寫在屏幕上
            write(1, buf, len);
      
            //close file
            close(fd);
            return 0;
        }

rename函數

  • 函數定義

    int rename(const char *oldpath, const char *newpath);
  • 功能

    文件重命名。

二、Linux目錄操做相關函數

chdir函數

  • 函數定義

    int chdir(const char *path);
  • 功能

    修改當前進程的路徑。

getcwd函數

  • 函數定義

    char *getcwd(char *buf, size_t size);
  • 功能

    獲取當前進程工做目錄。

mkdir函數

  • 函數定義

    int mkdir(const char *pathname, mode_t mode);
  • 功能

    建立目錄。
      注意:建立的目錄須要有執行權限,不然沒法進入目錄。

rmdir函數

  • 函數定義

    int rmdir(const char *pathname);
  • 功能

    刪除一個空目錄。

opendir函數

  • 函數定義

    DIR *opendir(const char *name);
  • 功能

    打開一個目錄。

readdir函數

  • 函數定義

    struct dirent *readdir(DIR *dirp);
  • 功能

    讀目錄。
  • 返回值

    struct dirent {
          ino_t          d_ino;       /* 此目錄進入點的inode */
          off_t          d_off;       /* 目錄文件開頭至此目錄進入點的位移 */
          unsigned short d_reclen;    /* d_name的長度,不包含NULL字符 */
          unsigned char  d_type;      /* d_name所指的文件類型 */
          char           d_name[256]; /* 文件名 */
      };
    
      d_type:
      DT_BLK      This is a block device.
      DT_CHR      This is a character device.
      DT_DIR      This is a directory.
      DT_FIFO     This is a named pipe (FIFO).
      DT_LNK      This is a symbolic link.
      DT_REG      This is a regular file.
      DT_SOCK     This is a UNIX domain socket.
      DT_UNKNOWN  The file type is unknown.
    
      -D_BSD_SOURCE 編譯時添加宏定義

colsedir函數

  • 函數定義

    int closedir(DIR *dirp);
  • 功能

    關閉目錄。
  • 示例

    #include <stdio.h>
      #include <stdlib.h>
      #include <sys/types.h>
      #include <dirent.h>
    
      int get_file_count(char * root)
      {
          DIR * dir = NULL;
          dir = opendir(root);
          if(dir == NULL)
          {
              perror("opendir");
              exit(1);
          }
    
          struct dirent * ptr = NULL;
          char path[1024] = {0};
          int total = 0;
          while(ptr = readdir(dir) != NULL)
          {
              //過濾.和..
              if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
              {
                  continue;
              }
              //若是是目錄
              if(ptr->d_type == DT_DIR)
              {
                  sprintf(path, "%s/%s", root, ptr->d_name);
                  total += getFileNum(path);
              }
              //若是是文件
              if(ptr->d_type == DT_REG)
              {
                  total++;            
              }
          }
    
          closedir(dir);
          return total;
      }
    
      int main(int argc, char * argv[])
      {
          if(argc < 2)
          {
              printf("./a.out dir\n");
              exit(1);
          }
    
          int total = get_file_count(argv[1]);
          printf("%s has file numbers %d\n", argv[1], total);
    
          return 0;
      }

六、fcntl函數

  • 函數定義

    int fcntl(int fd, int cmd, ... /* arg */ );
  • 功能

    改變已經打開的文件的屬性。
      一、複製一個現有的描述符 -- cmd
              F_DUPFD
      二、獲取/設置文件描述符標記 -- cmd
              F_GETFD
              F_SETFD
      三、獲取/設置文件狀態標記 -- cmd
              F_GETFL
                          O_RDONLY        只讀打開
                          O_WRONLY        只寫打開
                          O_RDWR          讀寫打開
                          O_EXEC          執行打開
                          O_SEARCH        搜索打開目錄
                          O_APPEND        追加寫
                          O_NONBLOCK      非阻塞模式
    
              F_SETFL, 可更改的幾個標識
                          O_APPEND
                          O_NONBLOCK
      四、獲取/設置異步I/O全部權 -- cmd
              F_GETOWN
              F_SETOWN
      五、獲取/設置記錄鎖 -- cmd
              F_GETLK
              F_SETLK
              F_SETLKW
  • 示例

    #include <stdio.h>
      #include <stdlib.h>
      #include <fcntl.h>
      #include <unistd.h>
      #include <string.h>
    
      int main(int argc, char * argv[])
      {
          int fd;
          int flag;
    
          //測試字符串
          char * p = "we are family!";
          cahr * q = "yes, man.";
    
          //只寫的方式找開文件
          fd = open("test.txt", O_WRONLY);
          if(fd == -1)
          {
              perror("open");
              exit(1);
          }
    
          //輸入新的內容,該部分會覆蓋原來舊的內容
          if(write(fd, p, strlen(p)) == -1)
          {
              perror("write");
              exit(1);
          }
    
          //使用F_GETFL命令獲得文件狀態標誌
          flag = fcntl(fd, F_GETFL, 0);
          if(flag == -1)
          {
              perror("fcntl");
              exit(1);
          }
    
          //將文件狀態標誌添加「追加寫」選項
          flag |= O_APPEND;
          //將文件狀態修改成追加寫
          if(fcntl(fd, F_SETFL, flag) == -1)
          {
              perror("fcntl -- append write");
              exit(1);
          }
    
          //再次輸入新內容,該內容會追加到舊內容的後面
          if(write(fd, q, strlen(q)) == -1)
          {
              perror("write again");
              exit(1);
          }
    
          //關閉文件
          close(fd);
          return 0;
      }

七、dup, dup2函數

  • 函數定義

    int dup(int oldfd);
      int dup2(int oldfd, int newfd);
  • 功能

    複製現有的文件描述符。
  • 返回值

    dup返回的是文件描述符中沒有被佔用的最小的文件描述符
  • 注意事項

    dup2兩種狀況:
      一、old --> new, 若是new是一個被打開的文件描述符,在拷貝前先關掉new。
      二、old和new是同一個文件描述符,不會關掉new,直接返回old。
  • dup示例

    #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <unistd.h>
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
    
      int main()
      {
          int fd = open("a.txt", O_RDWR);
          if(fd == -1)
          {
              perror("open");
              exit(1);
          }
    
          printf("file open fd = %d\n", fd);
    
          //找到進程文件描述表中==第一個==可用的文件描述符
          //將參數指定的文件複製到該描述符後,返回這個描述符
          int ret = dup(fd);
          if(ret == -1)
          {
              perror("dup");
              exit(1);
          }
          printf("dup fd = %d\n", ret);
          char * buf = "你是猴子派來的救兵嗎???\n";
          char * buf1 = "你大爺的,我是程序猿!!!\n";
    
          write(fd, buf, strlen(buf));
          write(ret, buf1, strlen(buf1));
    
          close(fd);
          return 0;
      }
  • dup2示例

    #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <unistd.h>
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
    
      int main()
      {
          int fd = open("english.txt", O_RDWR);
          if(fd == -1)
          {
              perror("open");
              exit(1);
          }
    
          int fd1 = open("a.txt", O_RDWR);
          if(fd1 == -1)
          {
              perror("open");
              exit(1);
          }
    
          printf("file open fd = %d\n", fd);
          printf("file open fd1 = %d\n", fd1);
    
          //調用dup2後,fd1和fd同時指向了a.txt
          int ret = dup2(fd1, fd);
          if(ret == -1)
          {
              perror("dup2");
              exit(1);
          }
          printf("current fd = %d\n", ret);
          char * buf = "主要看氣質^_^!!!!!!!!!!!\n";
    
          write(fd, buf, strlen(buf));
          write(fd1, "hello, world!", 13);
    
          close(fd);
          close(fd1);
          return 0;
      }
  • 解決gcc編譯過程當中c99語法報錯的問題

    alias gcc='gcc -std=gnu99'
  • 索引節點inode:保存的實際上是實際的數據的一些信息,這些信息稱爲「元數據」(也就是對文件屬性的描述)。例如:文件大小,設備標識符,用戶標識符,用戶組標識符,文件模式,擴展屬性,文件讀取或修改的時間戳,連接數量,指向存儲內容的磁盤區塊的指針,文件分類等等。(注意數據分紅:元數據+數據自己)

  • 注意inode怎樣生成的:每一個inode節點的大小,通常是128字節或256字節。inode節點的總數,在格式化時就給定(現代OS能夠動態變化),通常每2KB就設置一個inode。通常文件系統中不多有文件小於2KB的,因此預約按照2KB分,通常inode是用不完的。因此inode在文件系統安裝的時候會有一個默認數量,後期會根據實際的須要發生變化。

  • 注意inode號:inode號是惟一的,表示不一樣的文件。其實在Linux內部的時候,訪問文件都是經過inode號來進行的,所謂文件名僅僅是給用戶容易使用的。當咱們打開一個文件的時候,首先,系統找到這個文件名對應的inode號;而後經過inode號,獲得inode信息,最後,由inode找到文件數據所在的block,如今能夠處理文件數據了。

  • inode與文件的關係:當建立一個文件的時候,就給文件分配了一個inode。一個inode只對應一個實際文件,一個文件也會只有一個inode。inode最大數量就是文件的最大數量。

相關文章
相關標籤/搜索