Linux

Bash 程式設計教學與範例:判斷檔案、目錄是否存在

介紹各種在 Bash 指令稿中判斷檔案或目錄是否存在的方法與技巧,並提供實用範例。

檢查檔案是否存在

在 Bash 中可以使用 test 指令搭配 -f 參數來檢查指定的檔案是否存在:

# 要檢查的檔案
FILE=/etc/resolv.conf

# 使用 test 檢查檔案是否存在
if test -f "$FILE"; then
  echo "$FILE 檔案存在"
else
  echo "$FILE 檔案不存在"
fi
/etc/resolv.conf 檔案存在

test 指令還有另外一種中括號的寫法,這種寫法適用於所有符合 POSIX 標準的 shell,如果想要讓指令稿具有較高的可移植姓,就要採用這種寫法:

# 使用 [ 檢查檔案是否存在
if [ -f "$FILE" ]; then
  echo "$FILE 檔案存在"
else
  echo "$FILE 檔案不存在"
fi

除了單中括號之外,還有另外一種新式的雙中括號的寫法,這種寫法改善了單中括號的缺點(例如可以省略引號),但是只適用於較新的 shell(例如 Bash、Zsh 與 Ksh):

# 使用 [[ 檢查檔案是否存在
if [[ -f $FILE ]]; then
  echo "$FILE 檔案存在"
else
  echo "$FILE 檔案不存在"
fi

簡略寫法

如果我們只是要在某個檔案存在時執行某個指令,可以改用以下這種簡略寫法,只有在指定檔案存在時才會執行 && 之後的指令:

# 當檔案存在時,才執行指令(test 指令寫法)
test -f "$FILE" && echo "$FILE 檔案存在"

# 當檔案存在時,才執行指令(單中括號寫法)
[ -f "$FILE" ] && echo "$FILE 檔案存在"

# 當檔案存在時,才執行指令(雙中括號寫法)
[[ -f $FILE ]] && echo "$FILE 檔案存在"

若要執行多行指令,可以將多行指令用大括號包起來,並以分號(;)或 && 分隔:

# 當檔案存在時,才執行指定的多行指令
[ -f "$FILE" ] && { echo "$FILE 檔案存在"; cp "$FILE" /tmp/; }

若要使用簡略寫法依據檔案是否存在執行不同指令,可以這樣寫:

# 依據檔案是否存在執行不同指令
[ -f "$FILE" ] && echo "$FILE 檔案存在" || echo "$FILE 檔案不存在"

檢查目錄是否存在

若要檢查指定目錄是否存在,可以使用 test 指令搭配 -d 參數:

# 要檢查的目錄
DIR=/var/log

# 檢查目錄是否存在
if [ -d "$DIR" ]; then
  echo "$DIR 目錄存在"
else
  echo "$DIR 目錄不存在"
fi

使用 && 的簡略寫法:

# 當目錄存在時,才執行指令
[ -d "$DIR" ] && echo "$DIR 目錄存在"

這裡只示範中括號的寫法,另外兩種寫法以此類推。

檢查檔案或目錄是否存在

test-f 參數適用於檔案,而 -d 參數適用於目錄,若不想區分檔案或目錄,只檢查存在與否,可以改用 -e 參數。

# 要檢查的檔案或目錄
PATH=/var/log/nginx

# 檢查檔案或目錄是否存在
if [ -e "$PATH" ]; then
  echo "$PATH 檔案或目錄存在"
else
  echo "$PATH 檔案或目錄不存在"
fi

檢查檔案是否不存在

如果只需要對檔案不存在的狀況進行處理,可以用這樣的寫法:

# 要檢查的檔案
FILE=/etc/not.exist

# 使用 test 檢查檔案是否不存在
if ! test -f "$FILE"; then
  echo "$FILE 檔案不存在"
fi

# 使用 [ 檢查檔案是否不存在
if [ ! -f "$FILE" ]; then
  echo "$FILE 檔案不存在"
fi

# 使用 [[ 檢查檔案是否不存在
if [[ ! -f $FILE ]]; then
  echo "$FILE 檔案不存在"
fi

以簡略寫法檢查檔案是否不存在:

# 當檔案不存在時,才執行指令(test 指令寫法)
test -f "$FILE" || echo "$FILE 檔案不存在"

# 當檔案不存在時,才執行指令(單中括號寫法)
[ -f "$FILE" ] || echo "$FILE 檔案不存在"

# 當檔案不存在時,才執行指令(雙中括號寫法)
[[ -f $FILE ]] || echo "$FILE 檔案不存在"

檢查多個檔案是否存在

若要一次檢查多個檔案是否都存在,可以搭配 -a 參數(代表 AND 運算):

# 要檢查的檔案
FILE1=/etc/resolv.conf
FILE2=/etc/fstab

# 使用 test 檢查兩個檔案是否皆存在
if test -f "$FILE1" -a -f "$FILE2"; then
  echo "$FILE1$FILE2 檔案皆存在"
fi

# 使用 [ 檢查兩個檔案是否皆存在
if [ -f "$FILE1" -a -f "$FILE2" ]; then
  echo "$FILE1$FILE2 檔案皆存在"
fi

如果要檢查至少一個檔案存在的狀況,可以搭配 -o 參數(代表 OR 運算):

# 使用 test 檢查是否至少存在一個檔案
if test -f "$FILE1" -o -f "$FILE2"; then
  echo "$FILE1$FILE2 至少其中一個檔案存在"
fi

# 使用 [ 檢查是否至少存在一個檔案
if [ -f "$FILE1" -o -f "$FILE2" ]; then
  echo "$FILE1$FILE2 至少其中一個檔案存在"
fi

另外一種寫法是使用 shell 中的 &&|| 運算子:

# 使用 [ 檢查兩個檔案是否皆存在
if [ -f "$FILE1" ] && [ -f "$FILE2" ]; then
  echo "$FILE1$FILE2 檔案皆存在"
fi

# 使用 [ 檢查是否至少存在一個檔案
if [ -f "$FILE1" ] || [ -f "$FILE2" ]; then
  echo "$FILE1$FILE2 至少其中一個檔案存在"
fi

範例指令搞

以下是一個完整的指令稿範例,它會從參數讀取檔案名稱,逐一檢查每個路徑是否存在,並判斷是檔案還是目錄。

#!/bin/bash
# 從參數列讀取路徑
for PATH in ${@}; do
  # 檢查路徑是檔案或目錄
  if [ -f "$PATH" ]; then
    echo "$PATH 檔案存在"
  elif [ -d "$PATH" ]; then
    echo "$PATH 目錄存在"
  else
    echo "$PATH 檔案或目錄不存在"
  fi
done

將這段指令稿儲存為 check_path.sh 後,即可用來檢查檔案或目錄:

# 檢查各路徑是檔案或目錄
./check_path.sh /etc/resolv.conf /var/log /not/exist
/etc/resolv.conf 檔案存在
/var/log 目錄存在
/not/exist 檔案或目錄不存在

參考資料:Linuxizedevconnected

Share
Published by
Office Guide
Tags: Bash

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago