こんにちは、私はディレクトリパスをパラメータとして使用し、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>&1
for を削除して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
}
ls
Cロケールのエラーメッセージは、次のパターンに従うと仮定します*: fixed error message
。fixed error message
ここで、各エラー条件は異なりますが、特定のエラーに対して常に同じであり、次のものは含まれません:
(私のシステムでのみETOOMANYREFS
(参照が多すぎて接続できません。)対応する標準のlibcエラーメッセージにありますが、これはとにかく返されたerrnoでは:
ありません。lstat()
接合できない他のエラーメッセージでは見つかりません)。
AKAは[
最初はtest
サポートされていません-e
。最初にksh
導入されました-a
(その後、単項演算子と二項演算子で2倍になります)。アクセシビリティ私はそれが後で名前が変わったと信じています-e
(ほとんどの実装ではまだそれをサポートしていますが-a
)。これは-e
、POSIXが標準test
/[
ユーティリティに対して指定したものです。/bin/sh
Solaris 10以前にはまだPOSIXではなくBourneシェルがあり、組み込み機能はまだNorを[
サポートしていません。したがって、そのシェルを使用するには、以下を使用または呼び出す必要があります。そこのようなPOSIXシェル)。[ -e
[ -a
ls
/bin/test
/usr/xpg4/bin/sh