Bo2SS

Bo2SS

8 文件與目錄、AWK

文件讀取、權限控制、AWK 文本處理

課程內容#

目錄#

  • cd:切換工作目錄
    • 參數缺省:回到自己的家,[PS] C 語言不支持缺省參數,可通過宏實現
    • 參數~:回到自己的家,可使用 [~ 用戶名] 的方式指定該用戶名的家
    • 參數 -:回到上次目錄,適合兩個長路徑的相互切換
  • pwd
    • -L 邏輯工作目錄
    • -P 物理工作目錄【真實】
    • 主要體現在軟連接
      • ln -s [要連接的文件] [軟連接的位置 / 或 软连接的位置 / 软连接名]
      • 兩者在同一片物理空間,物理目錄一致
      • 【刪除】對於軟連接 test 指向一個文件夾
        • [rm test] 只刪除這個連接文件
        • [rm -r test/] 會刪除連接的文件夾裡的所有內容,危險!
          • 雖然該操作會提示 test / 不是一個目錄,但 test / 下已經乾乾淨淨
          • 如果連接的是文件不是文件夾,不影響原內容
      • [PS] 硬連接不能用在目錄上
  • mkdir
    • -p 自動創建父目錄,當想創建多級目錄時
    • -m 設置權限
    • 示例:mkdir -p -m 700 ./test/abc/x
  • rmdir:可用 rm 替代
  • 絕對路徑:從根目錄 / 開始
  • 相對路徑:從當前目錄。或上層目錄.. 開始

文件與目錄的管理#

  • ls:顯示文件及目錄信息
  • cp:拷貝
    • -i 若文件存在,詢問
    • -r 遞歸
    • -a = -pdr
      • p 拷貝時連同文件屬性
      • d 拷貝連接文件而不是其指向
      • r 遞歸
    • -u 源文件比目標文件新才拷貝,適合大容量備份
    • -s 拷貝為軟連接;-l 拷貝為硬連接
    • cp/mv 多個文件時,最後一個必須是目錄
    • ⭐cp 的實現邏輯
      • 打開文件 → 讀文件 → 寫文件
      • 【如果 cp 的是一個管道】
        • 那需要從另一端傳入數據,才能讀取數據再寫
        • cp 完後,拷貝結果為存儲管道數據的普通文件
  • rm:刪除
    • -i 互動模式,會詢問
    • -r 遞歸
    • -f 強制
  • mv:移動
    • 本質就是 cp + rm
    • -i、-f、-u,類似 cp
  • basename:取文件名;dirname:取目錄名
    • 不會判斷有沒有文件
    • basename /home/xxx/abc → abc
    • dirname /home/xxx/abc → /home/xxx
    • 一般在 shell 腳本中用
  • rename:可以被 cp、mv 取代

文件內容的查閱#

  • cat:正向連續讀 [反向:tac]
    • -A = -vET
      • -v 顯示一般看不到的符號
      • -E 顯示斷行符為 $ [同 vim 下 list、 nolist]
      • -T 顯示 TAB 為 ^I
      • [PS] 如果有 \0...stray 錯誤(拷貝別人代碼時),可以用 - A 看看特殊字符
    • -b 列出行號;-n 連同空行列出行號
  • nl:輸出行號顯示文件
    • 選項 [選項參數]👈它倆有順序講究
    • -b [a/t] 行號指定的方式 → 對應 [cat -n/cat -b]
    • -n [ln/rn/rz] 列出行號的表示方法
    • -w [num] 行號所占位數
    • 一般用於特殊文本
  • more、less、head、tail
    • more 和 less 的區別
      • more 只能往下翻,搜索沒有高亮
      • less 更靈活,可以上下翻,搜索有高亮
    • 取 21 - 40 行:man ls | head -n 40 | tail -n -20 【去尾、掐頭,sed 也能實現】
  • od 以二進制方式查看文件內容,暫時用不到,具體操作見課程速記

修改文件時間與新建文件#

  • 三個時間
    • mtime [modify]:修改時間【默認顯示】
    • ctime [change]:權限修改時間
    • atime [access]:訪問時間(記錄成本很高)
    • [PS] Mac 下有更多的時間類型,與 Linux 不兼容
  • touch 文件
    • 主要用來修改時間
    • 如果不存在,會自動創建
    • 特殊用法用的少,詳見課程速記
    • [PS] 可以把文件的時間改回去,不讓人感知

文件隱藏屬性#

可通過 chattr [+/- 選項] 更改

  • A:不修改 atime [可提高效率、磁碟壽命]
  • S:同步寫入
    • 指 IO 同步,避免斷電沒保存 [斷電後內存裡的數據直接消失]
  • a:只能增加數據 [日誌]
    • 不能修改,不能刪除,即使是 sudo
    • 在 vim 下不能修改,但修改 [不用 sudo] 會產生沒有 a 屬性的備份文件
  • i:不能刪除、修改、建立連接 [默認為硬連接],相當於【固化】
  • s:文件刪除時,直接從磁碟刪除
    • 正常情況下,刪除文件,只是把文件與對應磁碟位置的關係解除,內容其實還在磁碟裡,有點像 C 語言的 free ()
    • 加了 s 屬性後,刪除文件會將磁碟裡的數據全部置 0,真正的重寫清空
    • 這裡一般指機械硬碟,固態硬碟又另說
  • 【lsattr】查看文件隱藏屬性
    • [PS] 軟連接似乎沒有隱藏屬性

文件的特殊權限#

| 權限 | 權限占位符 | 作用對象 | 效果 |
|:----:|:----:|:----:|:----|:----:|:----|:----:|:----|
|set_uid|s | 二進制程序文件,非腳本 | 執行該程序時獲得程序所有者權限 |
|set_gid|s | 二進制程序文件,目錄 | 在該目錄下,有效組變為目錄所屬組 |
|sticky bit|t | 目錄 | 在該目錄下,用戶只能刪除自己創建的內容 |

可通過 chmod [u/g/ 空 |+/-|s/t] 更改

  • set_uid
    • ⭐chmod u+s,針對所屬用戶權限
    • 占所屬用戶權限的 x 的位置:如果存在 x,則變為 s;不存在,則變為 S
    • 舉例:其他用戶通過 passwd 命令修改密碼
      • 圖片
      • 其他用戶對存放密碼的文件 /etc/shadow 沒有任何權限
      • 但 passwd 命令有 s 權限,所以其他有執行權限的用戶在執行時獲得程序所有者權限,從而可以修改密碼文件 /etc/shadow
  • set_gid
    • ⭐chmod g+s,針對所屬組權限
    • 占所屬組權限的 x 的位置:如果存在 x,則變為 s;不存在,則變為 S
    • 在這個目錄裡做的事情都是以【目錄所屬組】的身份做的
    • 一般作用於目錄
      • 而對於二進制程序文件,有點類似 set_uid,但獲得的是【所屬】的權限
    • 方便協同辦公,以組為單位管理目錄下的所有用戶
  • sticky bit 黏著位
    • ⭐chmod +t,可參考粘滯位—— 維基百科
    • 占其他用戶權限的 x 的位置:如果存在 x,則變為 t;不存在,則變為 T
    • 舉例:/tmp 目錄及目錄下的一些目錄

命令與文件的查詢#

  • which:尋找可執行文件
    • 在 PATH 路徑下查找
    • 在 zsh 下 ls 是 ls --color=tty 的別名,它會被第二條命令的 ls 誤認為是多個路徑
      • 圖片
      • 查看 which 的選項,可以通過 which -p ls 對 ls 只做【路徑搜索】
        • 圖片
        • 圖片
        • 學會使用命令替換符
  • whereis:尋找更多類型的文件,可指定特定類型
    • -b 只查找二進制文件
    • -m 只查找 man 手冊中的文件
    • -s 只查找源文件
    • -u 查找其他文件
  • locate:模糊定位
    • -i 忽略大小寫
    • 基於數據庫,不是實時更新的,可使用 [sudo] updatedb 馬上更新

find:高級查找#

【時間】

  • -mtime、-ctime、-atime [單位為天]
    • <--__+n___|__n__|__-n__|:n天之前 [不包含n] | n天前的一天內 | n天內 [包含n]
    • image-20201216223627330
    • 分鐘為單位可查看 man 手冊:-mmin、-cmin、-amin
  • ⭐創建一個文件,文件及當前目錄的 mtime 都會被修改
    • 因為每個目錄有一張文件表,裡面記錄文件名和 inode
    • 當目錄裡增加了一個文件,該文件表也就多了一個文件名及 inode
    • 所以當前目錄的 mtime 也會變
    • ❗ 但如果只是修改一個文件,很好理解,當前目錄的 mtime 不會改變
  • -newer file 以文件時間作為時間節點

【用戶、用戶組】

  • -user 指定 user 名
    • 查找用戶 hz 在 10 分鐘內活躍的進程 ID 【PID】
    • 圖片
    • 進程文件在 /proc 下,都是虛擬的,文件 [目錄] 大小為 0
    • 應用:殺死進程
    • [PS] 進程 ID 和 inode 不是一回事,不能殺 inode
  • -uid、-gid、-group、nouser、nogroup 的使用同 - user

【文件、文件權限】

  • -name 匹配文件名
    • 圖片
    • (... -o ...) 邏輯或,注意括號用 \ 轉義,兩端裡面有空格
    • xargs—— 參數代換,不需要再移到前面用命令替換符
  • -size [+ 大於 - 小於]
    • 可以查找空文件,用來做清理,但要注意一些特殊文件 [.py 等]
  • -type
    • 7 種文件類型:f b c d l s p
  • -perm 775/-775
    • 後者包含前者,即 - 775 包括 775、776、777
  • -exec find 自帶的執行工具
    • 圖片
    • 統計已編寫的 c、cpp、sh 代碼行數
    • -exec— 命令的開始
    • {} —— find 的結果
    • ; —— 命令的結束

➕AWK 文本數據處理#

awk [-Ffv] 'BEGIN { commands } pattern { commands } END { commands } file'
  • 常用選項

    • -F fs:指定分隔符 fs,可以是字符或正則表達式,默認為空格
    • -v var=value:傳遞外部變量 var 給 awk
    • -f scriptfile:從腳本文件 scriptfile 讀取 awk 命令
  • BEGIN {}:開始執行一次

  • pattern {}:重點⭐

    • awk 讀取的每一行都會執行一次
    • 如果沒有提供 pattern 語句塊,則默認執行 {print}
  • END {}:最後執行一次

  • [PS]

    • 可以從文件 file 讀取數據,也可以用管道 "|" 傳遞數據
    • commands 支持各種語言的 print 函數,如 C 語言的 printf ()
  • 示例:統計最近登錄的總時長

    • 圖片
    • 先預處理數據
    • 圖片
    • 使用 awk 取到需要的時長數據
    • 圖片
    • 使用 awk 做計算
    • 常用內建變量:$n、NF、NR
  • 圖片
  • [PS]

    • 參考文檔 ——AWK 程序設計語言
    • 不用強背,知道它的功能即可
    • 其偏向於專業性;其實是一門語言,有自己的語法結構
    • 有很多變種
  • 圖片

附加知識點#

  • 對於 /var 下的 run 目錄:ls -al run/,ls -ald run/,ls -ald run
    • 三者的結果都不一樣,ls -ald run 也可以用 ls -al run
    • 注意斜杠 / 的存在
  • PATH 變量是在進程裡,斷開 SSH 後重連,PATH 變量會恢復原樣
    • 嚴格說是在內存裡
  • 管道文件 [mkfifo 創建的] 和管道 [命令中的 | ] 的區別
    • 本質上沒有區別:一進一出,沒輸入就會產生阻塞
    • 但是,| 隱含創建了一個進程,處理了數據後再返回給原進程
  • ⭐Linux 中,文本處理的基本單位:行
    • cat、tac、scanf、printf
  • 【硬連接】
    • 相當於一個文件多了一個別名,刪除一個別名不影響文件
    • 對於存在硬連接的 a、b 文件
      • 通過 ls -i 查看 inode [文件結點號]
      • 會發現 a、b 兩個文件的 inode 相同,且文件連接數為 2
  • chmod -R ...:遞歸,修改目錄及下面所有文件的權限
  • 解壓壓縮:gzip/gunzip、tar -c 壓縮 /-x 解壓 /-v 顯示冗餘信息 /-z 通過 gzip 操作
    • tar 不能解壓.gz 文件,使用 gunzip 即可
  • ⭐創建的目錄默認大小為 4096 Byte = 4K
    • 對應磁碟的一個 block,存儲的是一個文件表
    • ❗目錄大小不會為 0,/proc 下的大小為 0 的目錄,屬於虛擬文件系統,不是真的目錄

思考點#

  • C 的源文件被編譯後的 a.out,使用./a.out 執行,這裡的./ 是什麼意思
    • 沒有特殊含義,就是【當前路徑】,用的是相對路徑執行
    • 也可以使用絕對路徑執行
    • ❓直接 a.out 呢?
      • a.out 會被認為是命令,從而報錯 command not found
      • 對於默認的字符,系統默認為是執行命令,會找內置命令或去 PATH 路徑下找
        • 默認為命令而不是文件,因為命令更常用
  • 輸出重定向的細節
    • 圖片
    • 方式①:會排隊,按順序輸出
    • 方式②:同時傳,數據會亂序
    • &1 = 1 號文件
    • 此外,方式①還有順序要求
      • 圖片
      • 這樣,2 號文件沒有輸出到 1 號文件裡
      • 這裡順序有講究,得先打開 xxx.log 文件!
  • find 找不到文件時,再 ls 容易讓人產生錯覺
    • 圖片
    • 相當於 ls 空,即 ls 當前目錄

Tips#

  • 【避免 rm 危險操作】
    • 寫腳本定時 [contab] 將代碼上傳到 Github、碼雲
    • 把 rm 封裝改成 mv,給自己定義的回收站,寫腳本定時清理超過 3 天的文件
  • 【小技巧】shell 下,輸入一小部分代碼,按上下鍵可以匹配曾輸過的匹配的代碼
    • [其它] 使用驚嘆號!開頭
      • !mk 直接輸入在歷史記錄裡最近的匹配命令
      • !9812 直接輸入 history 裡第 9812 行
  • 一般 - r、-R 表示遞歸,可自己嘗試,小寫被佔用了就會用大寫
  • 聊到 link 默認指硬連接
  • man 手冊搜索參數時,使用 "/-z,",在後面加一個逗號,匹配數更少
  • $() 可以充當命令替換符 ``

課程速記#

  • 圖片
  • 圖片
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。