Bashラインで何が起こっているのかを段階的に説明できる人はいますか?私はここに初めて来ましたが、特にこのコードが次にどのように機能するかを理解しようとしていますecho
。
read char; echo -e "YES\nNO\n" | grep -i $char
答え1
char
この行のコマンドは、ユーザーが対話的に文字列を変数として読み込みます。
echo
+パイプはgrep
入力文字列が正の文字列であることを確認しようとします。大文字と小文字を区別せずに、入力文字列(入力文字列をパターンとして使用)YES
と単語の合計を比較してこれを行います。NO
ユーザーが単語の大文字、小文字、または部分文字列を入力すると結果はにYES
なりYES
、文字列の大文字、小文字、または部分文字列を入力すると結果はにNO
なりますNO
。このような内容を入力すると空のmaybe
出力が発生します。
このアプローチの欠点は、たとえば、ユーザーが と と入力すると、両方が一致することです。.
なぜなら、YES
ドットNO
はgrep
すべての文字に一致する正規表現として扱われるからです。$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
返されます。これは、ユーザーが単純な等以上のコンテンツを入力する必要があるという点で機能的に異なります。NO
yes
no
e
yes
答え2
いいですね。各コマンドを順番に実行しましょう。
read char
これは標準入力(通常はキーボードですが、間接ファイルまたはパイプストリームの場合があります、以下を参照)から読み取られ、受信したデータを名前付き変数に配置しますchar
。
echo -e "YES\nNO\n"
echo
提供された引数は標準出力(通常は端末)として印刷されます。この-e
スイッチ(通常は必ずしもそうではなく、echo
一貫した実装にはいくつかの問題があります)を使用すると、e
一部の基本フォーマットに対して特定の文字をエスケープできます。この場合、\n
エスケープされたを使用しており、n
ewlineの略ですn
。
grep -i $char
grep
提供されたパターンに一致する項目があるかどうかを確認するために提供された入力を検索するツールです。このスイッチは大文字と小文字を区別せずに検索-i
するように指示します。i
それとコマンド|
の間に「パイプ」があります。これは、第1のコマンドの出力を第2のコマンドの入力に接続する。つまり、数字は変数の内容に反映されたパターンを検索します。echo
grep
grep
char
YES
NO
このコマンドシーケンスの実際の結果は、提供された入力(変数名に基づいて単一文字と見なされますが解決されません)を見ることです。文字がY
、、、、またはの場合、E
出力はです。文字が、、、またはの場合、出力はです。ただし、(たとえば)入力がまたはの場合は何も出力されません。S
y
e
s
YES
N
O
n
o
NO
yo
ne
前述のように、入力が文字であるという仮定は確認されません。これは、与えられたコマンドシーケンスの例では唯一のアンチパターンではありません。たとえば、変数は参照されず、正規表現ツール(grep
)は入力の正規表現ワイルドカードフィルタリングなしで使用されています。
答え3
で「文字」(文字列ではない)を読みます/dev/stdin
。意味:自分で入力してください。
/dev/stdout
その後、コンソールを意味する2行が出力されます。
次に、パイプ("|")を介して大文字と小文字を区別しない入力バージョンに移動します。
つまり、「bar」と入力すると何も出力せずに完了しますが、「y」と入力すると「YES」行が出力され、「Y」も強調表示される可能性が高くなります。