Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux exec 與檔案描述符進階技巧:重導向、持久化、管道與 find 實戰

編輯:Linux 教學

檔案描述符 (FD) 基礎

  • 每個進程啟動預設開啟 3 個 FD:0 (stdin)、1 (stdout)、2 (stderr)。
  • FD 為非負整數,指向核心檔案表項目。
  • ulimit -n 查看/設定進程最大 FD 數 (預設 1024)。

exec 內建命令:不創建子進程,直接操作當前 Shell 的 FD

exec <重導向操作>   # 影響當前 Shell 後續所有命令
exec <操作符><目標>  # 任意 FD 操作

實戰案例集

案例 1:將檔案綁定到自訂 FD (讀寫雙向)

exec 3<> hello.txt      # FD 3 開啟 hello.txt 讀寫 (若不存在會建立)
echo "hello exec" >&3   # 寫入 FD 3 (從檔案開頭覆蓋)
echo "hello world" >&3  # 續寫
exec 3>&-               # 關閉 FD 3 寫入 (實際上也無法再讀)
# exec 3<&-             # 僅關閉讀取

案例 2:標準輸出永久重導向到檔案

exec 1> log.txt          # 後續所有 echo/printf 等輸出導向 log.txt
echo "this goes to log.txt"
# 恢復需見案例 3

案例 3:標準輸出重導向並稍後恢復 (核心技巧)

exec 100>&1            # ① 將 FD 100 複製標準輸出 (備份)
exec 1> log.txt        # ② 重導向 stdout 到檔案
echo "in log.txt"
exec 1>&100 100>&-     # ③ 恢復 stdout (1 指向 100),關閉備份 FD 100
echo "back to terminal"

原理: 100>&1 使 FD 100 指向 FD 1 當前指向的檔案表項;1>&100 再將 FD 1 指回該項。

案例 4:標準輸入重導向並恢復

exec 100<&0            # 備份 stdin
exec < input.txt       # stdin 來自檔案
read line1; echo "Line1: $line1"
read line2; echo "Line2: $line2"
exec 0<&100 100<&-     # 恢復 stdin
read -p "Manual input: " custom

案例 5:腳本內部讀寫檔案 (避免頻繁開關)

#!/bin/bash
OUTFILE="out.txt"; INFILE="in.txt"
: > "$OUTFILE"                 # 清空輸出檔
exec 4>&1                      # 備份 stdout 到 FD 4
exec 1> "$OUTFILE"             # stdout 導向輸出檔
while IFS= read -r line; do
    echo "$line: processed"
done < "$INFILE"
exec 1>&4 4>&-                 # 恢復 stdout,關閉 FD 4
echo "Done, check $OUTFILE"

find 配合 -exec 實戰

語法關鍵

find <路徑> <條件> -exec <命令> {} \;
# {} 會被替換為找到的檔案路徑
# \; 結束 -exec (需轉義防止 Shell 解釋)
# + 替換 \; 可批次傳遞多個檔案 (如 xargs),效率更高

常用範例

# 1. 找所有 .txt 並 grep "bin"
find . -name "*.txt" -exec grep "bin" {} \;

# 2. 刪除所有 .tmp (謹慎!)
find . -name "*.tmp" -exec rm {} \;

# 3. 批次修改擁有者
find /data -type f -exec chown www-data:www-data {} +

# 4. 壓縮超過 30 天的日誌
find /var/log -name "*.log" -mtime +30 -exec gzip {} +

# 5. 複製特定結構到備份目錄
find . -name "*.conf" -exec cp --parents {} /backup \;

進階:FD 陷阱與最佳實踐

陷阱說明對策
FD 洩漏迴圈中開啟 FD 未關閉,耗盡限額嚴格配對 exec N>&-/exec N<&-,或用 {var}<>file (Bash 4.1+) 自動分配未用 FD
子 Shell 不繼承 exec 修改(exec 1>file; echo hi) 不影響父 Shell在主 Shell 執行 exec,或用函數而非子 Shell
管道與 exec 衝突exec 1>file | cmd 管道優先避免同一命令混用管道與 exec 重導向
FD 數字衝突硬編碼 3,4,5 可能與其他部分衝突用 exec {var}>file 讓 Shell 自動分配 (Bash 4.1+)

自動分配 FD (Bash 4.1+) 推薦寫法

exec {LOG_FD}> log.txt
echo "Auto FD: $LOG_FD" >&$LOG_FD
exec {LOG_FD}>&-  # 關閉
# 讀取同理
exec {IN_FD}< input.txt
read line <&$IN_FD
exec {IN_FD}<&-

結語

exec 配合檔案描述符操作,是 Shell 腳本處理複雜 I/O 重導向、持久化檔案存取、實現雙向通訊的核心武器。掌握「備份 → 重導向 → 恢復」三步曲、善用自動分配 FD、結合 find -exec + 批次處理,能編寫出高效、健壯、易維護的自動化腳本。

Copyright © Windows教程網 All Rights Reserved