Shell-Script

在腳本中使用 glob 檢查子目錄是否存在

  • May 29, 2021

我正在嘗試檢查目錄bin是否位於有時會更改的目錄中。在這種特殊情況下,ruby 的版本號可以改變(例如$HOME/.gem/ruby/2.6.0/bin)。這是我到目前為止所做的:

#!/usr/bin/env zsh
ruby_gem_home="$HOME/.gem/ruby/*/bin"
if [[ -d $ruby_gem_home ]]; then
 echo "The ruby gems directory exists!"
else
 echo "Ruby gems directory missing!"
fi

我不想使用find,因為這是登錄過程的一部分。使用內置 zsh/bash 命令實現此目的最優雅的方式是什麼?

謝謝!

**編輯:**忘了提到這是一個zsh腳本。

使用數組,並檢查第一個元素(即

$$ 0 $$在 bash 中,$$ 1 $$在 zsh 中)的數組是一個目錄。例如在bash

# the trailing slash in "$HOME"/.gem/ruby/*/bin/ ensures that
# the glob matches only directories.
rubygemdirs=( "$HOME"/.gem/ruby/*/bin/ )

if [ -d "${rubygemdirs[0]}" ] ; then
  echo "At least one ruby gem dir exists"
else
  echo "No ruby gem dirs were found"
fi

要同時使用zshbash,您需要首先找出目前正在執行的 shell。這將告訴您數組的第一個索引是0還是1。它還將確定您是否需要(N)與 glob 一起使用來告訴 zsh 如果 glob 沒有匹配項則不要退出(預設情況下,zsh 將在 glob 匹配錯誤時退出)。

(此時,很明顯,編寫一個腳本以在 bash 和 zsh 中可靠地工作可能會比它的價值更麻煩)

if [ -n "$BASH_VERSION" ] ; then
  first_idx=0
  rubygemdirs=( "$HOME"/.gem/ruby/*/bin/ )
elif [ -n "$ZSH_VERSION"  ] ; then
  first_idx=1
  emulate sh
  rubygemdirs=( "$HOME"/.gem/ruby/*/bin/ )
  emulate zsh
fi

if [ -d "${rubygemdirs[$first_idx]}" ] ; then
...

如果需要,您還可以遍歷數組以檢查元素是否與特定版本匹配。例如

for d in "${rubygemdirs[@]}" ; do
 [[ $d =~ /2\.6\.0/ ]] && echo found gem dir for ruby 2.6.0
done

注意:/正則表達式中的 s 是文字正斜杠。他們沒有將正則表達式的開頭和結尾標記為sed.

引用自:https://unix.stackexchange.com/questions/651662