私はユーザーにドメイン名を求めるシェルスクリプトを書いています。ユーザーに入力内容を繰り返し入力し、有効なドメイン名でない場合は、エラーメッセージを作成するように求められます。
デフォルトでは、コードは次のようになります。
#!/bin/bash
read -p "Enter domain name: " DOMAIN_NAME
while [[ testing for valid domain name goes here ]]
do
echo ''
echo 'You entered an invalid domain name. Please re-enter.'
echo '... more error message data ....'
echo ''
read -p "Enter domain name: " DOMAIN_NAME
done
echo "You entered domain name: $DOMAIN_NAME"
"=~"演算子を使用して正規表現をテストする方法を示すいくつかの例を見つけました。しかし、これらの例はすべてUNTIL
ループを示しています。質問に対する回答に正規表現を使用してください。Bashで正規表現を使用して有効な(サブ)ドメインを確認する、例は次のとおりです。
# !/bin/bash
until [[ "$DOMAIN_NAME" =~ ^([a-zA-Z0-9](([a-zA-Z0-9-]){0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,5}$ ]]
do
read -p "Enter domain name: " DOMAIN_NAME
done
echo "You entered domain name: $DOMAIN_NAME"
この方法は機能しますが、ユーザーが誤ったデータを入力した場合、追加のエラーメッセージを作成するのは簡単ではありません。これらのメッセージはループ内、以前に作成する必要がありますread
が、最初の反復では作成されません。
このため、私はwhile
上記のようにループを書くことをお勧めします。until
ループをループに書き換えるwhile
ときに必要なテスト式を否定する方法が見つかりません。
答え1
until cmd
同じですwhile ! cmd
。
ここでは、次の操作を行います。
until
IFS= read -rep 'Enter domain name: ' domain
[[ $domain =~ $regexp ]]
do
printf>&2 'Invalid domain: "%s"\n' "$domain"
done
printf 'You entered: "%s"\n' "$domain"
それは次のとおりです。
while
IFS= read -rep 'Enter domain name: ' domain
! [[ $domain =~ $regexp ]]
do
printf>&2 'Invalid domain: "%s"\n' "$domain"
done
printf 'You entered: "%s"\n' "$domain"
または:
while
IFS= read -rep 'Enter domain name: ' domain
[[ ! $domain =~ $regexp ]]
do
printf>&2 'Invalid domain: "%s"\n' "$domain"
done
printf 'You entered: "%s"\n' "$domain"
ループの条件付き部分に/があるため、read
正規表現テストの前に毎回実行されますが、終了ステータスを確認しません。ループの分岐を決定することは、条件付きセクション(ここまたは)で実行される最後のコマンドです。while
until
[[ ... ]]
! [[ ... ]]
また、ロケールをCに変更したり、範囲がコードポイントに基づくzshなどのシェルに切り替えない限り、入力検証に文字範囲を使用できないことに注意してください。
#! /bin/zsh -
set -o extendedglob
until
domain=
vared -p 'Enter domain name: ' domain
[[ $domain = ([a-zA-Z0-9]([a-zA-Z0-9-](#c0,61)[a-zA-Z0-9]|).)##[a-zA-Z](#c2,5) ]]
do
printf>&2 'Invalid domain: "%s"\n' "$domain"
done
printf 'You entered: "%s"\n' "$domain"
(ここではvared
(var editor)組み込み機能を使用してbashなどのzsh行エディタを使用しますread -e
)。
グローバルパターンマッチングのためのwithの代わりに=~
正規表現マッチングにinを使用する場合は、このオプションを使用してPCREを使用していることを確認する必要があります。基本的にbashなどのEREを取得できますが、すべての制限があります。しかし、PCREはEREと同じであることを覚えておいてください。だから:zsh
=
rematchpcre
$
\z
regexp='^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,5}\z'
UTF-8ロケールで有効な文字を形成しない一連のバイトは、PCREエラーを引き起こします。 zsh globモードを使用すると、これらの問題をよりスムーズに処理できます。
BashでCロケールの外側でこの10文字だけを一致させるには(オプションが有効かどうかにかかわらず)、[0123456789]
代わりに必要です。または同じです。少なくともbashでは、変数にNULバイトを含めることはできないため、そのバイトと一致しない正規表現について心配する必要はありません。[0-9]
globasciiranges
[a-z]
[A-Z]
また覚えておいてください:
- bashで
read
はなしで使用したり、-r
使用せずに使用することはIFS=
ほとんど意味がありません。 echo
任意のデータを出力するために使用しないでください。- エラーはstderrに送信する必要があります。