bash このスクリプトを改善する方法

bash このスクリプトを改善する方法

私はシェルスクリプトに初めて触れましたが、私が思ったよりも優れた解決策があるかどうか疑問に思います。

ユーザーがリストにあることを確認したいと思います。その場合、スクリプトは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_programignore配列が空の場合、ループは単一の反復を実行しないため、配列が空であることをテストする必要はありません。

上記のコードでは、"${ignore[@]}"(二重引用符を参照)はユーザー名のリストに展開され、各ユーザー名は別々に引用され、追加のトークン化とファイル名の生成を防ぎます。

関連:


バージョンによって異なりますが、bashPOSIX と同様のシェルで実行できます。

set -- 'user1' 'user2' 'user3'

for u do
    if [ "$USER" = "$u" ]; then
        exit_program 'bye bye'
    fi
done

これは、無視するユーザー名のリストとして、配列ではなく位置引数のリストを使用します。

答え2

grepソリューション

単語を一致させるには、の「-w」機能を使用しますgrepgrepSolaris、AIXなどの以前の実装では機能しないと言いたいです。

echo $IGNORE_USER | grep -qw $USER && exit_program 'bye bye'

オンラインでお試しください!

bash 内部ソリューション

bashを完全に使用しgrep、 。

bash=~ regex最初に実行しないと、建設は許可されませんshopt -s compat31。したがって、=~ $(echo regex)私たちはこの問題を克服することができます。この例では、拡張を容易にするために二重引用符を使用しています。$USERこれを行うときは、\bbeにエスケープする必要があります\\b

[[ $IGNORE_USER =~ $(echo "\\b$USER\\b") ]] && exit_program 'bye bye'

オンラインでお試しください!

関連情報