Bashコマンドラインのread、echo、およびgrepコマンドについて

Bashコマンドラインのread、echo、およびgrepコマンドについて

Bashラインで何が起こっているのかを段階的に説明できる人はいますか?私はここに初めて来ましたが、特にこのコードが次にどのように機能するかを理解しようとしていますecho

read char; echo -e "YES\nNO\n" | grep -i $char

ベストアンサー1

charこの行のコマンドは、ユーザーが対話的に文字列を変数として読み込みます。

echo+パイプはgrep入力文字列が正の文字列であることを確認しようとします。大文字と小文字を区別せずに、入力文字列(入力文字列をパターンとして使用)YESと単語の合計を比較してこれを行います。NOユーザーが単語の大文字、小文字、または部分文字列を入力すると結果はにYESなりYES、文字列の大文字、小文字、または部分文字列を入力すると結果はにNOなりますNO。このような内容を入力すると空のmaybe出力が発生します。

このアプローチの欠点は、たとえば、ユーザーが と と入力すると、両方が一致することです。.なぜなら、YESドットNOgrepすべての文字に一致する正規表現として扱われるからです。$char呼び出しに引用符がないため、ユーザーがgrep入力/*/*/*/*/../../../../*/*/*/*などのシェルグローブパターンを入力した場合(たとえば、次から取得)bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスク)。-r -o -e . /たとえば、コマンドの出力を歪ませることもできます。例えば、(これは、各非バイナリファイルの各文字に対して、そのファイルが属するファイルのパス名の前に別々の行を出力します)。

あなたが示すコードは、本質的にユーザー入力を使用するという点で「奇妙で珍しい」です。パスワードつまり、ユーザー入力を次のように使用します。模様、静的テストデータこの可変パターンの場合。これは、ユーザーの入力を受け取り、静的スキーマに対してこの変更可能なデータをテストする通常行われる操作とは反対です。

次のようなコードを使用する方が一般的です。

read -p 'Yes/[N]o: ' yesno
if [[ $yesno == [Yy]* ]]; then
   # code for affirmative
else
   # code for non-affirmative
fi

上記のコードは、ユーザーから文字列を読み取り、文字列が文字またはy文字Yで始まるかどうかをテストします。そうであれば、ステートメントの最初の分岐が選択されif、それ以外の場合はデフォルトで選択されますelse

明らかに、単語全体をテストしたり、YES大文字[Yy][Ee][Ss]と小文字を区別せずに一致をテストしたり、検証を介して入力ループを変更したりできます。

while true; do
    read -p 'Yes/No: ' yesno

    if [ "$yesno" = Yes ] || [ "$yesno" = No ]; then
        break
    fi

    echo 'Please enter "Yes" or "No"' >&2
done

# $yesno is either Yes or No here

(または同様のもの)。

上記の2つのサンプルコードが、ユーザー入力をパターンではなくデータとしてのみ使用する方法に注意してください。

元のコマンドを少なくとも寛容なものに書き換えると(ただし、機能が異なり、完璧ではないかもしれません)

read yesno; printf '%s\n' "${yesno^^}" | grep -i -w -E 'yes|no'

ユーザーがまたはを入力すると、大文字またはがYES返されます。これは、ユーザーが単純な等以上のコンテンツを入力する必要があるという点で機能的に異なります。NOyesnoeyes

おすすめ記事