回答:
シェルスクリプトにディレクトリが存在するかどうかを確認するには、以下を使用できます。
if [ -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY exists.
fi
または、ディレクトリが存在しないかどうかを確認するには:
if [ ! -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY doesn't exist.
fi
ただし、Jon Ericsonが指摘しているように、ディレクトリへのシンボリックリンクもこのチェックに合格することを考慮に入れないと、後続のコマンドが意図したとおりに機能しない可能性があります。例えばこれを実行します:
ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then
rmdir "$SYMLINK"
fi
エラーメッセージが表示されます。
rmdir: failed to remove `symlink': Not a directory
したがって、後続のコマンドがディレクトリを想定している場合は、シンボリックリンクを別の方法で処理する必要があります。
if [ -d "$LINK_OR_DIR" ]; then
if [ -L "$LINK_OR_DIR" ]; then
# It is a symlink!
# Symbolic link specific commands go here.
rm "$LINK_OR_DIR"
else
# It's a directory!
# Directory command goes here.
rmdir "$LINK_OR_DIR"
fi
fi
変数をラップするために使用される二重引用符に特に注意してください。この理由については、8jean が別の回答で説明しています。
変数にスペースやその他の異常な文字が含まれていると、スクリプトが失敗する可能性があります。
[ ! -d "$DIRECTORY" ]
いずれかの場合にtrueになります$DIRECTORY
が存在しない場合、またはありませんが存在しますがディレクトリではありません。のようなものを考えてくださいif [ ! -d "$DIRECTORY" ] ; then mkdir "$DIRECTORY" ; fi
。"$DIRECTORY"
ファイルの場合、これは失敗します。(もちろん、mkdir
成功したかどうかを確認する必要があります。失敗する理由はいくつかあります。)
-d
)とシンボリックリンク(-L
)の両方をテストする代わりに、のように変数にスラッシュを追加する方が簡単if [ -d "${THING:+$THING/}" ]
です。ディレクトリは余分なスラッシュを気にしません。ファイルはfalseと評価されます。空は空のままなので、false。そして、シンボリックリンクはその宛先に解決されます。もちろん、それはあなたの目標次第です。あなたがそこに行きたいなら、これは大丈夫です。それを削除したい場合は、この回答のコードの方が優れています。
Bashスクリプトで変数を参照するときは、常に変数を二重引用符で囲むことを忘れないでください。最近の子供たちは、ディレクトリ名にスペースや他の多くの面白い文字を含めることができるという考えで成長しました。(スペース!昔、空想的なスペースはありませんでした!;))
ある日、子供たちの1人が$DIRECTORY
setを使用"My M0viez"
してスクリプトを実行し、スクリプトが爆発します。あなたはそれを望まない。これを使用してください。
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
-dテストは驚くべき結果をもたらす可能性があることに注意してください。
$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory
下のファイル:「ディレクトリはディレクトリではない場合」答え:「ディレクトリへのシンボリックリンクの場合」もう少し徹底的なテスト:
if [ -d t ]; then
if [ -L t ]; then
rm t
else
rmdir t
fi
fi
if [ -d tmpdir -a ! -L tmpdir ]; then echo "is directory"; rmdir tmpdir; fi
...または、リンクとディレクトリの両方で機能する1つのコマンド:rm -r tmpdir
の二重括弧バージョンを使用test
すると、論理テストをより自然に記述できます。
if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It's a bona-fide directory"
fi
if [[ -d "$TARFILE" ]]
私は[[取得しています:見つからない
[[ ]]
がサポートされていますが、実際にはに別の機能を提供していません[ ]
。移植性が懸念される場合は[ ]
、必要な回避策をそのまま使用します。
短い形式:
[ -d "$DIR" ] && echo "Yes"
if $dir is a dir, then echo "yes"
か?少し説明すると役立つでしょう:)
set -e
(これはシェルプログラミングのベストプラクティスです)。
[ -d "$DIR" ]
はチェックされる(が続く&& echo Yes
)のでset -e
、スクリプトの動作に違いはないと思います(つまり、テストが失敗した場合、スクリプトは正常に続行します)。
ディレクトリが存在するかどうかを確認するには、次のif
ような単純な構造を使用できます。
if [ -d directory/path to a directory ] ; then
# Things to do
else #if needed #also: elif [new condition]
# Things to do
fi
ネガティブでそれを行うこともできます:
if [ ! -d directory/path to a directory ] ; then
# Things to do when not an existing directory
注:注意してください。開始と終了の両方のブレースの両側に空白を残します。
同じ構文で使用できます:
-e: any kind of archive
-f: file
-h: symbolic link
-r: readable file
-w: writable file
-x: executable file
-s: file size greater than zero
ディレクトリまたはファイルが存在するかどうかをテストする簡単なスクリプト:
if [ -d /home/ram/dir ] # For file "if [-f /home/rama/file]"
then
echo "dir present"
else
echo "dir not present"
fi
ディレクトリが存在するかどうかを確認する簡単なスクリプト:
mkdir tempdir # If you want to check file use touch instead of mkdir
ret=$?
if [ "$ret" == "0" ]
then
echo "dir present"
else
echo "dir not present"
fi
上記のスクリプトは、ディレクトリが存在するかどうかを確認します
$?
最後のコマンドが成功した場合は「0」を返し、それ以外の場合はゼロ以外の値を返します。仮定しtempdir
、既に存在しています。次にmkdir tempdir
、以下のようなエラーが発生します。
mkdir:ディレクトリ 'tempdir'を作成できません:ファイルが存在します
使用できますtest -d
(を参照man test
)。
-d file
ファイルが存在し、それがディレクトリであれば真。
例えば:
test -d "/etc" && echo Exists || echo Does not exist
注:test
コマンドは条件式と同じ[
(参照man [
:)なので、シェルスクリプト間で移植できます。
[
-これはtest
組み込みの同義語ですが、最後の引数は、開始と]
一致するようにリテラルでなければなりません[
。
可能なオプションまたは詳細なヘルプについては、以下を確認してください。
help [
help test
man test
または man [
または完全に役に立たないもののために:
[ -d . ] || echo "No"
非常に実用的なイディオムを次に示します。
(cd $dir) || return # Is this a directory,
# and do we have access?
私は通常それを関数にラップします:
can_use_as_dir() {
(cd ${1:?pathname expected}) || return
}
または:
assert_dir_access() {
(cd ${1:?pathname expected}) || exit
}
このアプローチの良い点は、適切なエラーメッセージを考える必要がないことです。
cd
標準エラーへの標準的な1行のメッセージが既に表示されます。また、私が提供できる以上の情報を提供します。cd
サブシェル内で実行することにより( ... )
、コマンドは呼び出し元の現在のディレクトリに影響を与えません。ディレクトリが存在する場合、このサブシェルと関数は何もしません。
次に渡す引数は次のcd
とおり${1:?pathname expected}
です。これは、以下でより詳細に説明する、より複雑な形式のパラメーター置換です。
Tl; dr:この関数に渡された文字列が空の場合、サブシェルを再び終了( ... )
し、指定されたエラーメッセージで関数から戻ります。
ksh93
manページからの引用:
${parameter:?word}
parameter
が設定され、null以外の場合 は、その値を置き換えます。それ以外の場合は、印刷word
してシェルを終了します(対話型でない場合)。もしword
省略された標準メッセージがプリントされます。
そして
コロンなら
:
上記の式からが省略されているシェルはパラメーターが設定されているかどうかのみをチェックします。
ここでの表現は、次のように、シェルのドキュメントに固有のものです。 word
、空白を含む任意の適切な文字列を指す場合があるです。
この特定のケースでは、標準エラーメッセージが 1: parameter not set
では不十分であることので、ここで想定している値のタイプにズームインします。pathname
ディレクトリます。
哲学ノート:
シェルはオブジェクト指向言語ではないので、メッセージにはpathname
、ではなく、と書かれていdirectory
ます。このレベルでは、私はそれを単純に保ちたいです-関数への引数は単なる文字列です。
test -d
@Grundlefleckが説明したとおりです。
test -d /unreadable/exists
引数が存在していても失敗します。
if [ -d "$Directory" -a -w "$Directory" ]
then
#Statements
fi
上記のコードは、ディレクトリが存在するかどうか、および書き込み可能かどうかをチェックします。
Bashプロンプトで次のコードを入力します。
if [ -d "$DIRECTORY" ]; then
# If true this block of code will execute
fi
find
サブディレクトリ内のフォルダの存在を確認します。
found=`find -type d -name "myDirectory"`
if [ -n "$found"]
then
# The variable 'found' contains the full path where "myDirectory" is.
# It may contain several lines if there are several folders named "myDirectory".
fi
現在のディレクトリ内のパターンに基づいて、1つまたは複数のフォルダーの存在を確認します。
found=`find -maxdepth 1 -type d -name "my*"`
if [ -n "$found"]
then
# The variable 'found' contains the full path where folders "my*" have been found.
fi
両方の組み合わせ。次の例では、現在のディレクトリにフォルダーが存在するかどうかを確認します。
found=`find -maxdepth 1 -type d -name "myDirectory"`
if [ -n "$found"]
then
# The variable 'found' is not empty => "myDirectory"` exists.
fi
find -maxdepth 1 -type d -name 'pattern'
。私はあなたの答えにこのトリックを追加してもよろしいですか?乾杯;)
実際には、防弾アプローチを得るためにいくつかのツールを使用する必要があります。
DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # Now you're testing
echo "It's a dir";
fi
を使用している限り、スペースや特殊文字を気にする必要はありません"${}"
。
注[[]]
などの携帯型としてではない[]
が、ほとんどの人は(すべての後、ほとんどの人は、コマンドライン:-Pでも、仕事をしないので)バッシュの最近のバージョンで動作するので、利益が悩みよりも大きくなります。
if
飛躍する前に見るのではなく、やりたいことを何でもすることを考えましたか?
つまり、入力する前にディレクトリの存在を確認する場合は、次のようにします。
if pushd /path/you/want/to/enter; then
# Commands you want to run in this directory
popd
fi
指定したパスがpushd
存在する場合は、そのパスを入力するとで終了します。0
つまりthen
、ステートメントの一部が実行されます。存在しない場合は、何も起こりません(ディレクトリが存在しないことを示す出力がある場合を除き、これはおそらくデバッグに役立つ副作用です)。
これは自分自身を繰り返す必要があるこれよりも良いようです:
if [ -d /path/you/want/to/enter ]; then
pushd /path/you/want/to/enter
# Commands you want to run in this directory
popd
fi
同じことはで動作するcd
、mv
、rm
あなたが存在しないファイルでそれらをしようとした場合、彼らはエラーで終了し、それが存在しない旨のメッセージを印刷し、あなたのよ...、などthen
のブロックはスキップされます。存在するファイルでそれらを試すと、コマンドが実行され、ステータスで終了し、ブロックを実行0
できますthen
。
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"
注意:変数を引用することは良い習慣です。
説明:
-d
:ディレクトリかどうかを確認-L
:シンボリックリンクかどうかを確認する複数のディレクトリを確認するには、次のコードを使用します。
if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
# Things to do
fi
ディレクトリが存在するかどうかを確認し、そうでない場合は次のようにします。
[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
mkdir -p "$DIRECTORY"
、同じ効果のために。
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
この答えはシェルスクリプトとしてまとめました
$ is_dir ~
YES
$ is_dir /tmp
YES
$ is_dir ~/bin
YES
$ mkdir '/tmp/test me'
$ is_dir '/tmp/test me'
YES
$ is_dir /asdf/asdf
NO
# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
echo "Folder doesnt exist: $DIR";
exit;
fi
function show_help()
{
IT=$(CAT <<EOF
usage: DIR
output: YES or NO, depending on whether or not the directory exists.
)
echo "$IT"
exit
}
if [ "$1" == "help" ]
then
show_help
fi
if [ -z "$1" ]
then
show_help
fi
DIR=$1
if [ -d $DIR ]; then
echo "YES";
exit;
fi
echo "NO";
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists
fi
これは完全に真実ではありません...
そのディレクトリに移動する場合は、そのディレクトリに対する実行権限も必要です。多分あなたも同様に書き込み権限を持っている必要があります。
したがって:
if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
# ... to go to that directory (even if DIRECTORY is a link)
cd $DIRECTORY
pwd
fi
if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
# ... to go to that directory and write something there (even if DIRECTORY is a link)
cd $DIRECTORY
touch foobar
fi
file
プログラムを使用します。Linuxではすべてのディレクトリもファイルであるため、次のコマンドを発行するだけで十分です。
file $directory_name
存在しないファイルを確認する: file blah
出力: cannot open 'blah' (No such file or directory)
既存のディレクトリを確認する: file bluh
出力: bluh: directory
このls
コマンドと-l
(長いリスト)オプションを組み合わせて使用すると、ファイルとディレクトリに関する属性情報が返されます。
特に、ls -l
出力の最初の文字は通常a d
またはa -
(ダッシュ)です。以下の場合にはd
記載されているかわからためのディレクトリです。
次の1行のコマンドは、指定さISDIR
れた変数にディレクトリへのパスが含まれているかどうかを示します。
[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directory"
実用的な使い方:
[claudio@nowhere ~]$ ISDIR="$HOME/Music"
[claudio@nowhere ~]$ ls -ld "$ISDIR"
drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
[claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directory"
YES, /home/claudio/Music is a directory.
[claudio@nowhere ~]$ touch "empty file.txt"
[claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt"
[claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directoy"
Sorry, /home/claudio/empty file.txt is not a directory
file="foo"
if [[ -e "$file" ]]; then echo "File Exists"; fi;
実際のディレクトリかシンボリックリンクかに関係なく、ディレクトリが存在するかどうかを確認する場合は、次のようにします。
ls $DIR
if [ $? != 0 ]; then
echo "Directory $DIR already exists!"
exit 1;
fi
echo "Directory $DIR does not exist..."
説明:「ls」コマンドは、ディレクトリーまたはシンボリック・リンクが存在しない場合、エラー「ls:/ x:No such file or directory」を出し、「$?」を介して取得できる戻りコードをnonに設定します-null(通常は "1")。「ls」を呼び出した直後に、必ず戻りコードを確認してください。
if ! ls $DIR 2>/dev/null; then echo "$DIR does not exist!"; fi
(1)
[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"
(2)
[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"
(3)
[[ -d run_dir && ! -L run_dir ]] && echo Exists || echo "Not Exists"
上記のいずれかの方法で問題が見つかった場合:
ls
コマンド; ディレクトリが存在しない場合-エラーメッセージが表示されます
[[ `ls -ld SAMPLE_DIR| grep ^d | wc -l` -eq 1 ]] && echo exists || not exists
-ksh:not:not found [該当するファイルまたはディレクトリはありません]
すばらしい解決策はたくさんありますが、適切なディレクトリにいないと、最終的にすべてのスクリプトが失敗します。したがって、次のようなコード:
if [ -d "$LINK_OR_DIR" ]; then
if [ -L "$LINK_OR_DIR" ]; then
# It is a symlink!
# Symbolic link specific commands go here
rm "$LINK_OR_DIR"
else
# It's a directory!
# Directory command goes here
rmdir "$LINK_OR_DIR"
fi
fi
実行時に、たまたま確認したサブディレクトリがあるディレクトリにいる場合にのみ、正常に実行されます。
私はこのような最初の質問を理解しています。ファイルシステム内のユーザーの位置に関係なく、ディレクトリが存在するかどうかを確認することです。したがって、コマンド 'find'を使用するとうまくいく場合があります。
dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d
このソリューションは、ファイル/ディレクトリを検索するときに便利な機能であるワイルドカードを使用できるため、優れています。唯一の問題は、検索されたディレクトリが存在しない場合、「find」コマンドは標準出力に何も出力せず(私の好みのためのエレガントなソリューションではありません)、それにもかかわらずゼロの出口があります。たぶん誰かがこれを改善できるでしょう。
locate
が付けられたツールには良いかもしれませんが、他には何もいいわけではないかもしれません...
--
は、使用を強くお勧めします(オプション終了マーカー)。それ以外の場合、変数にオプションのように見えるものが含まれていると、スクリプトはスペースと同様に失敗します。