私が収集しているものから、使用するときにそれを確認したい
tee -- "$OUT_FILE"
(--または-で始まるファイル名では動作しないことに注意してください)、tee書き込み用にファイルを開くことに成功します。
それはそれ:
- ファイルパスの長さがPATH_MAX制限を超えない
- ファイルは(シンボリックリンク解決後)存在し、タイプディレクトリではなく、書き込み許可があります。
- ファイルが存在しない場合、ファイルのディレクトリ名は(シンボリックリンク解決後)ディレクトリとして存在し、ファイルへの書き込みおよび検索許可があり、ファイル名の長さはディレクトリが存在するファイルシステムのNAME_MAX制限を超えません。
- または、ファイルは存在しないファイルを指すシンボリックリンクであり、シンボリックリンクループではありませんが、上記の基準を満たします
ファイル名に含まれるバイト値、ディスククォータ、プロセス制限、selinux、apparmorまたはその他のセキュリティメカニズム、フルファイルシステム、iノードが残っていない、デバイスに制限があるvfat、ntfs、hfsplusなどのファイルシステムは今のところ無視します何らかの理由でその方法で開くことができないファイル、現在何らかのプロセスアドレス空間にマップされている実行可能ファイルはすべて、ファイルを開くまたは作成する機能に影響を与える可能性があります。
でzsh:
zmodload zsh/system
tee_would_likely_succeed() {
local file=$1 ERRNO=0 LC_ALL=C
if [ -d "$file" ]; then
return 1 # directory
elif [ -w "$file" ]; then
return 0 # writable non-directory
elif [ -e "$file" ]; then
return 1 # exists, non-writable
elif [ "$errnos[ERRNO]" != ENOENT ]; then
return 1 # only ENOENT error can be recovered
else
local dir=$file:P:h base=$file:t
[ -d "$dir" ] && # directory
[ -w "$dir" ] && # writable
[ -x "$dir" ] && # and searchable
(($#base <= $(getconf -- NAME_MAX "$dir")))
return
fi
}
でbash、または任意のBourneシェルのような、単に置き換えます
zmodload zsh/system
tee_would_likely_succeed() {
<zsh-code>
}
で:
tee_would_likely_succeed() {
zsh -s -- "$@" << 'EOF'
zmodload zsh/system
<zsh-code>
EOF
}
ここでのzsh固有の機能は、$ERRNO(最後のシステムコールのエラーコードを公開する)および$errnos[]対応する標準Cマクロ名に変換する連想配列です。そして$var:h(cshから)および$var:P(zsh 5.3以降が必要)。
bashには同等の機能がまだありません。
$file:hdir=$(dirname -- "$file"; echo .); dir=${dir%??}またはGNU で置き換えることができますdirname:IFS= read -rd '' dir < <(dirname -z -- "$file")。
の場合$errnos[ERRNO] == ENOENT、アプローチls -Ldはファイルで実行し、エラーメッセージがENOENTエラーに対応するかどうかを確認することです。しかし、これを確実かつ移植性のある方法で行うのは難しいです。
1つのアプローチは次のとおりです。
msg_for_ENOENT=$(LC_ALL=C ls -d -- '/no such file' 2>&1)
msg_for_ENOENT=${msg_for_ENOENT##*:}
(エラーメッセージがのsyserror()翻訳で終了し、ENOENTその翻訳にが含まれていないと仮定して:)、次に、の代わりに[ -e "$file" ]、
err=$(ls -Ld -- "$file" 2>&1)
そして、ENOENTエラーをチェックします
case $err in
(*:"$msg_for_ENOENT") ...
esac
この$file:P部分はbash、特にFreeBSDで達成するのが最も難しいものです。
FreeBSDにはrealpathコマンドとオプションreadlinkを受け入れるコマンド-fがありますが、ファイルが解決しないシンボリックリンクの場合は使用できません。それは同じだperlさんCwd::realpath()。
pythonさんは、os.path.realpath()と同様に動作しているように見えないzsh $file:Pの少なくとも一つのバージョンがあると仮定して、pythonインストールされていることをpython、あなたが行うことができます(FreeBSD上で与えられていない)、それらのものをいうコマンドは:
dir=$(python -c '
import os, sys
print(os.path.realpath(sys.argv[1]) + ".")' "$dir") || return
dir=${dir%.}
しかし、その後、同様にすべてを行うこともできますpython。
または、これらすべてのコーナーケースを処理しないこともできます。