ディレクトリにファイルがあることを確認する

ディレクトリにファイルがあることを確認する

こんにちは、私はディレクトリパスをパラメータとして使用し、file.txtがディレクトリにあることを確認するifタスクを実行しようとしています。その場合は 1 を返し、そうでない場合は 0 を返します。

     if [ -e $1/file.txt ]; then
         exit 1
     else exit 0
     fi

私もlsメソッドを試しました

     ls $1/file.txt && exit 1 || exit 0

別の方法がありますか?それとも私が何かを見逃しているのでしょうか?

答え1

file.txtスクリプトまたは関数に最初の引数として渡されたディレクトリにファイルがあるかどうかを確認するには、次のようにします。

[ -e "$1/file.txt" ]

変数の置換を二重引用符で引用することを忘れないでください。

ファイルが存在する場合は成功、ファイルがない場合は失敗します。失敗には、ファイルは存在するがアクセスできない状況が含まれます。たとえば、ディレクトリを閲覧する権限がないためです。

シェルスクリプトのプロセス終了状態に関して、0は成功を意味し、1(またはそれ以上、最大125)は失敗を意味します。バラよりBash関数/スクリプトでどの戻り/終了値を使用できますか?そしてプロセスの終了時にデフォルトの終了コードは何ですか?詳細については。したがって、ファイルが存在することを確認するには、スクリプトまたは関数は、ファイルが存在する場合は0を返し、そうでない場合は1を返す必要があります。コードスニペットは反対のタスクを実行します。つまり、ファイルが存在しないことを確認します。

 if [ -e "$1/file.txt" ]; then
    exit 0
 else
    exit 1
 fi

もっと複雑な書き込み方法

[ -e "$1/file.txt" ]
exit

exitステータスパラメータがない場合は、以前に実行されたコマンドのステータスが使用されます。)これがスクリプトの最後にある場合は重複exitします。

!ファイルが存在しないことを確認するには、シェル演算子を使用してコマンドを逆にすることができます。

! [ -e "$1/file.txt" ]

または! test/[演算子:

[ ! -e "$1/file.txt" ]

答え2

[ -e "$1/file.txt" ]

これをサポートするシェル/実装で[パスstat()$1/file.txt

これは次のとおりです。

if ls -Ld -- "$1/file.txt" > /dev/null 2>&1

以下と同じ:

if ls -d -- "$1/file.txt" > /dev/null 2>&1

つまりlstat()、ファイルに対して操作を実行できる場合は次のようになります。

if [ -e "$1/file.txt" ] || [ -L "$1/file.txt" ]

「壊れた」シンボリックリンクケースをオーバーライドします(-eシンボリックリンク解決後に存在するかどうかをテストするときにfalseを返します)。

これで、失敗stat()lstat()必ずしもファイルが存在しないという意味ではありません。 / stat()ENOENT lstat()(項目なし)ENOTDIR(パスコンポーネントがディレクトリではない)以外のエラー条件が原因で失敗する可能性があります。たとえば、カタログコンポーネントへの検索アクセス権がない場合があります。

これlsにより2>&1for を削除してlsエラーを通知できます。それで、あなたができる場所を[使わないとわかりません。zsh$ERRNO

持っていない場合探すディレクトリにアクセスしても読むアクセス権があるので、ディレクトリの内容を読み、同じ名前のファイルがあることを確認できます。

の場合、zsh匿名関数でこれを行うことができます。 globに一致するファイルのリストを渡す()(($#)) $1/file.txt(N)引数()を1つ以上受け取ると、匿名関数はglobが開いていることを返します。()(($#))$1/file.txt(N)(N)NULLGLOB

別の問題は、$1/file.txt一部のシステムの場合とは異なる場合です。$1///file.txt/file.txt

したがって、ディレクトリにエントリがあることをzsh確認するには、次のようにします。file.txt$1

exists() {
  local file="${1%/}/file.txt"

  zmodload zsh/system
  local ERRNO=0
  [ -e "$file" ] || [ -L "$file" ] && return 0
  case $errnos[ERRNO] in
    (ENOENT|ENOTDIR) return 1;; # does not exist for sure
    (*) ()(($#)) $file && return 0;;
  esac
  return 2 # meaning: don't know
}

他のシェルの場合は、次のことを試すことができます。

enoent_error=$(
  LC_ALL=C ls -d /surely-does-not-exist 2>&1)
)
enoent_error=${enoent_error##*:}

enotdir_error=$(
  LC_ALL=C ls -d /bin/sh/foo)
)
enotdir_error=${enotdir_error##*:}

exists() (
  file=${1%/}/file.txt
  if error=$(LC_ALL=C ls -d -- "$file" 2>&1 > /dev/null); then
    return 0 # exists for sure
  else
    case $error in
      (*:"$enoent_error"|*:"$enotdir_error")
        return 1;; # does not exist for sure
    esac
  fi
  return 2 # don't know
}

lsCロケールのエラーメッセージは、次のパターンに従うと仮定します*: fixed error messagefixed error messageここで、各エラー条件は異なりますが、特定のエラーに対して常に同じであり、次のものは含まれません:(私のシステムでのみETOOMANYREFS参照が多すぎて接続できません。)対応する標準のlibcエラーメッセージにありますが、これはとにかく返されたerrnoでは:ありません。lstat()接合できない他のエラーメッセージでは見つかりません)。


AKAは[最初はtestサポートされていません-e。最初にksh導入されました-a(その後、単項演算子と二項演算子で2倍になります)。アクセシビリティ私はそれが後で名前が変わったと信じています-e(ほとんどの実装ではまだそれをサポートしていますが-a)。これは-e、POSIXが標準test/[ユーティリティに対して指定したものです。/bin/shSolaris 10以前にはまだPOSIXではなくBourneシェルがあり、組み込み機能はまだNorを[サポートしていません。したがって、そのシェルを使用するには、以下を使用または呼び出す必要があります。そこのようなPOSIXシェル)。[ -e[ -als/bin/test/usr/xpg4/bin/sh

関連情報