私はシェルスクリプトに初めて触れましたが、私が思ったよりも優れた解決策があるかどうか疑問に思います。
ユーザーがリストにあることを確認したいと思います。その場合、スクリプトはexit_program関数を使用して終了する必要があります。
$USER はシステムにログインした人物として定義されます。
私の解決策は次のとおりです。
$IGNORE_USER="USER1 USER2 USER3"
if [ ! -z "$IGNORE_USER" ]; then
for usr in $IGNORE_USER
do
if $USER = $usr; then
exit_program "bye bye"
fi
done
fi
答え1
このスクリプトの機能は次のとおりです。いいえ働く
ペアの割り当てはIGNORE_USER
逆参照変数を使用してはいけないため、最初の行に構文エラーがあります$
。あなたのステートメントに別の構文エラーがありますif
。文字列を比較するために使用されます[ "string1" = "string2" ]
。
$IGNORE_USER
あなたのコードは引用符なしで使用することに依存しています。これにより、文字列がスペースに分割されます。これは望ましい仕事です。最も一般的なケースは次のとおりです。いいえしかし、あなたが望むのは、リスト内のアイテムが保持されるべき空白文字を含む可能性が高いということです。引用符のない文字列を使用すると、シェルは文字列の値に対してファイル名の生成(ワイルドカード)も実行します。
個々のアイテム(ユーザー名)を処理するときは、配列を使用することをお勧めします。別のアイテムを次のように処理したいときはいつでも分離アイテムを単一の文字列に入れないでください。これを行うと、あるアイテムを他のアイテムと区別するのが難しくなります。
提案:
ignore=( 'user1' 'user2' 'user3' )
for u in "${ignore[@]}"; do
if [ "$USER" = "$u" ]; then
exit_program 'bye bye'
fi
done
これはexit_program
プログラムの終了に責任があります。そうでない場合は、exit
通話後に追加してくださいexit_program
。ignore
配列が空の場合、ループは単一の反復を実行しないため、配列が空であることをテストする必要はありません。
上記のコードでは、"${ignore[@]}"
(二重引用符を参照)はユーザー名のリストに展開され、各ユーザー名は別々に引用され、追加のトークン化とファイル名の生成を防ぎます。
関連:
バージョンによって異なりますが、bash
POSIX と同様のシェルで実行できます。
set -- 'user1' 'user2' 'user3'
for u do
if [ "$USER" = "$u" ]; then
exit_program 'bye bye'
fi
done
これは、無視するユーザー名のリストとして、配列ではなく位置引数のリストを使用します。
答え2
grepソリューション
単語を一致させるには、の「-w」機能を使用しますgrep
。grep
Solaris、AIXなどの以前の実装では機能しないと言いたいです。
echo $IGNORE_USER | grep -qw $USER && exit_program 'bye bye'
bash 内部ソリューション
bashを完全に使用しgrep
、 。
bash
=~ regex
最初に実行しないと、建設は許可されませんshopt -s compat31
。したがって、=~ $(echo regex)
私たちはこの問題を克服することができます。この例では、拡張を容易にするために二重引用符を使用しています。$USER
これを行うときは、\b
beにエスケープする必要があります\\b
。
[[ $IGNORE_USER =~ $(echo "\\b$USER\\b") ]] && exit_program 'bye bye'