ユーザーに質問し、答えを提供し、iという変数に保存するようにし、答え(ファイル)が存在し、書き込み可能な場合はそれを読み、内容を把握します。ファイルと挿入このコンテンツは新しいコンテンツに書き込まれます。ファイルが存在しない場合、またはユーザーがファイルに対する十分な権限を持っていない場合は、警告メッセージが表示され、プログラムは3秒間スリープモードに入り、ループを再開します。なぜ動作しないのですか?警告は消えず、サイクルは続行されません。
echo "$(tput setaf 4) Tell me where the file is:"
printf "\n"
a=false
while [ $a=true ]; do
read i
if [ -w $i ]
then cat $i | grep stuff > i2
else
a=true
printf "Oh something is wrong, try again!"
sleep 3
fi
done
答え1
文法的、論理的なエラーがあります。
これは$a=true
比較操作ではなく単純な文字列です。簡単に比較できるようにスペースで区切ります。"$a" = true
。
これを完了したら、あらかじめ設定しておいたので、ループにまったく入らなくなりますa=false
。
ループに陥ると、それ以外のものにa
設定されたことがなく、true
他のシャットダウンメカニズムが提供されないため(たとえばbreak
)シャットダウンできません。
答え2
他の人が指摘したように、コードには論理エラーと構文エラーがあります。これシェルチェックのウェブサイト文法エラーを解決するのに役立ちます。
ここに私の意見があります。 2つのバージョンのコードがあります。 (私が好む)最初のものはユーザー対話を持っていませんが、コマンドラインでパス名を使用します。 2番目は対話的にパス名を求めます。
対話的にパス名の入力を求められない最初の理由は、スクリプトユーザーがコマンドラインまたはスクリプトプロンプトでパス名を書き込んだ場合は違いがなく、パス名にスクリプトプロンプトを使用すると違いがないためです。たとえば、クローン操作や端末が接続されていない他の場所で使用できます。
#!/bin/sh
pathname=$1
if ! grep 'pattern' <$pathname >i2; then
echo 'Something is wrong' >&2
fi
上記の文は、echo
次の場合に実行されます。
$pathname
のファイルを読み込めない- ファイル
i2
に書き込めない - パターンが見つかりません
$pathname
(あなたのコードとは異なりますが、以下を参照してください)
一般的な診断メッセージをカスタマイズするのと同様に、エラーメッセージは標準エラーに記録されます。
インタラクティブなプロンプトと遅延:
#!/bin/bash
while true; do
read -r -p 'Pathname: ' pathname
if grep 'pattern' <$pathname >i2; then
break
fi
echo 'Something is wrong' >&2
sleep 3
done
grep
これには、ユーザーからデータを読み取り、呼び出しが正常な場合にループから出る無限ループがあります。何らかの理由で(上記の3つの理由のいずれか)失敗すると、パス名の入力をgrep
求められます。
どちらのコードも読み取り可能なファイルに対して別々のテストを持っています(grep
何も見つからないか、出力ファイルに書き込めないため失敗する可能性があります)。
まず、非対話型バージョン:
#!/bin/sh
pathname=$1
if [ ! -r "$pathname" ]; then
echo 'Something is wrong' >&2
fi
grep 'pattern' <$pathname >i2
そしてインタラクティブなバージョンがあります。
#!/bin/bash
while true; do
read -r -p 'Pathname: ' pathname
if [ -r "$pathname" ]; then
grep 'pattern' <$pathname >i2
break
fi
echo 'Something is wrong' >&2
sleep 3
done
または、ループがユーザー入力と検証のみを処理する対話型バージョン:
#!/bin/bash
while true; do
read -r -p 'Pathname: ' pathname
[ -r "$pathname" ] && break
echo 'Something is wrong' >&2
sleep 3
done
grep 'pattern' <$pathname >i2
答え3
次のように、単純な中断を使用して無限ループを停止してみてください。
echo "$(tput setaf 4) Tell me where the file is:"
echo # This prints empty line like printf "\n"
while true; do # 'while true' or 'while :' is infinite loop
read i
if [ -r $i ] # You probably mean -r (readable) and not -w (writable)
then
cat $i | grep stuff > i2
break # 'break' ends loop
else
echo -n "Oh something is wrong, try again!" # 'echo -n' means print without newline character
sleep 3
fi
done
修正に関するコメントと説明があります。