プロンプトで指定されたフルパスに基づいてディレクトリを生成するプログラムを実行しようとしていますが、ディレクトリがすでに存在する場合はエラー(「ディレクトリはすでに存在します」)を返し、再帰関数。
私が試したことは次のとおりです。test1
次のようなファイルがあるとしましょう。
#!/bin/bash
echo "enter the directory name"
read ab
check(){
if (( echo `mkdir $ab` 2>/dev/null )); then
echo "directory created "
echo `ls -ld $ab`
exit
else
echo "try again "
echo "enter new value for directory:"
read ab
check
fi
}
check
ここでの問題は、ディレクトリが存在する場合はプログラムが正常に動作しますが、存在しない場合はディレクトリを作成し、プログラムの別の部分に移動することです。
答え1
エコはいつも成功します。それとサブシェルがない場合:
#!/bin/bash
echo "enter the directory name"
read ab
check(){
if mkdir "$ab" 2>/dev/null; then
echo "directory created "
ls -ld "$ab"
exit
else
echo "try again "
echo "enter new value for directory: "
read ab
check
fi
}
check
答え2
(( echo `mkdir $ab` 2>/dev/null )) bash: ((: echo 2>/dev/null : syntax error in expression (error token is "2>/dev/null ")
二重括弧算術表現。このコマンドは、期待したものと同様の操作を行いません。mkdir $ab
標準出力には何も記録されないので`mkdir $ab`
空の文字列なので、算術式の内容になりますecho 2>/dev/null
。ここで、記号は変数名>
「より大きい」演算子です。echo
算術式の構文が正しくありません(変数の後にリテラル整数が続くことはできません)。コマンドの構文が正しくないため、エラー状態を返し、else
ブランチを使用します。
コマンドの戻り状態をテストするには、コマンドを作成します。
if mkdir -- "$ab" 2>/dev/null
追加のヒント:
- コマンドでエラーを隠すのは良い考えではありません。ユーザーは、エラーが許可拒否、I/O エラーなどであるかどうかを知る必要があります。存在しない場合はディレクトリを作成し、すでに存在する場合は成功するにはを使用します
mkdir -p -- "$ab"
。 - 変数の置換には常に二重引用符を使用してください。。
- 値が
ab
ダッシュで始まる場合、オプションとして解釈されます。--
表示されたオプションの最後を最初に配置します。
答え3
tries=0
while [ "$((tries+=1))" -le 5 ] || ! break
printf 'enter dirname: > '
IFS= read -r dir &&
if ! mkdir -- "$dir"
then echo try again
else ! echo Success\!
fi
do :; done
なぜこのような終了状態を無効にするのかはわかりませんが、上記は、探している反転に似たものを取得し、限られた数で動作する必要があると思います$tries
。
実行すると…?
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
そしてまた…
enter dirname: > doesntexist
Success!
答え4
このアイデアは状況を少し複雑にしますが、スクリプトで適切なテストを利用する方がより適切なアプローチであることを示唆しています。いくつかの効果:
#!/bin/bash
if [[ -n $1 ]]; then
dirname=$1
fi
if [[ -z $dirname ]]; then
echo "Enter directory name."
read dirname
fi
check() {
if [[ -d "$dirname" ]]; then
echo "Directory already exists."
echo "Enter new directory name."
read dirname
check
elif [[ -e "$dirname" ]]; then
echo "$dirname already exists, but is not a directory."
echo "Enter new directory name."
read dirname
check
else
if mkdir -p -- "$dirname"; then
echo "Directory created"
ls -ld "$dirname"
fi
exit
fi
}
check
これにより、呼び出し(mkdir)のエラーメッセージが保存され、いくつかの便利なテストが実行され、試行が失敗した理由に関するフィードバックが得られます。オプションで、必要なディレクトリ名をコマンドライン引数として渡すこともでき、2回目の試行でのみ入力するように求められます。