gitを自動的にインストール/削除するためにこのスクリプトを作成しました。 gitがインストールされているかどうかをテストする関数は、コマンドを使用してgit --version
戻りコードをテストします。
私はクールなカスタム出力を作成しようとしているので、通常どおりstderr出力が好きではありません。この機能に対してのみstderrを抑制する方法を見つけましたが、再度有効にすることはできません。
この関数を呼び出すと、read
プロンプトは消えます。
function CheckGit() {
exec 3>&2 # link file desc 3 w/ stderr
exec 2> /dev/null
SILENT_MODE=$1
if [[ ! $(git --version) ]]; then
if [ SILENT_MODE ]; then
printf "${LT_RED} GIT IS NOT INSTALLED.\n"
fi
continue;
else
if [ SILENT_MODE ]; then
printf "${LT_BLUE} GIT IS CURRENTLY INSTALLED.\n"
fi
continue;
fi
GIT_INSTALLED=$?
#turn back on the stderr notifications
exec 2>&3 3>&- # Restore stdout and close file descriptor #3
}
while true; do
printf "${LT_BLUE} Menu\n"
printf " ***********************************************\n"
printf "${LT_GREEN} a) Check git.\n"
printf "${LT_GREEN} b) (More to be added)\n"
printf "${LT_GREEN} c) ...\n"
printf "${LT_GREEN} d) ...\n"
printf "${LT_GREEN} h) ...\n"
printf "${LT_RED} x) Exit.\n"
printf "\n${NC}"
read -p "Please make a selection: " eotuyx
case $eotuyx in
[Aa]* ) CheckGit true; continue;;
[Bb]* ) ...; continue;;
[Cc]* ) ...; continue;;
[Dd]* ) ...; continue;;
[Hh]* ) ...; continue;;
[XxQq]* ) break;;
* ) -e "\n${NC}" + "Please answer with a, b, c, d, x(or q).";;
esac
done
答え1
与えられたアドバイスを繰り返すコメントから:
continue
関数から文を削除しますCheckGit
。- それらは必要ありません。
- そして - あなたはそれを認識できないかもしれません - これは(関数から)メインループにすぐに返されるだけでなく、メインループの
while true
上部にあるステートメントにすぐに返されます。したがって、次のようにトーマスは指摘した、あなたのexec 2>&3 3>&-
文が実行されていません。
一般:
if [ SILENT_MODE ]
いつも正しいからMosviが指摘した。これは、文字列がSILENT_MODE
空でないかどうかをテストするだけです。あなたがしたいようですif [ "$SILENT_MODE" ]
。- しかし、冗談かもしれません。 is が true
if [ "$SILENT_MODE" ]
の場合でも実行する操作は、文字列が null でないかどうかをテストするだけなので、呼び出すと情報が表示されます。$SILENT_MODE
false
CheckGit false
- そして、自分をだましていなくても、来週このスクリプトを維持する必要がある人をだますこともできます。はい、その人はまさにあなたかもしれません。あなたの明白なロジックは、「自動モードの場合は追加情報を報告してください」です。これは論理的に反対です。
if [ "$SILENT_MODE" = false ]
変数を話すか呼び出す方が合理的ですVERBOSE_MODE
。 $?
寿命は非常に短いです。いつもこんな結果が出ますね最近の注文。 だから、そうすればもし Gitがインストールされていることを確認する;その後 printf "GITがインストールされていません。\n" その他 printf "GIT が現在インストールされています。\n" フィリピン諸島 GIT_INSTALLED = $?
次にGIT_INSTALLED
終了ステータスを取得しますprintf
。GIT_INSTALLED
事前に設定してください。- あなたのテストは、
if [[ ! $(git --version) ]]; then
「戻りコード」(あなたの質問で言及されているように)をテストするのではなく、git --version
標準出力に記録されているものがあるかどうかをテストすることです。これはあなたが望むものかもしれません。これがgit
インストールされているかどうかをテストする最良の方法です。ただし、コマンドの終了ステータスを確認する方が良いかもしれません(通常は良いかもしれません)。 - スタイル注:
if
「本物」の部分が最初に来ると、文を理解するのは簡単ですthen
。else
あなたのスクリプトは次のように言いますGitがインストールされていない場合 それから インストールされていないそうです。 そうでない場合(つまり、いいえインストールされていません) すでにインストールされていると言います。 フィリピン諸島
二重否定は混乱しています。 - そしてそうです。
exec 2> /dev/null
42個の連続した文の標準エラーを抑制したい場合に便利です。単一のコマンドにのみ影響を与える必要がある場合は、次のようにそのコマンドに2> /dev/null
(または)を入力します。> /dev/null 2>&1
より良い提案。
答え2
コマンドは良く見えますが、ロジックがすべてのケースをカバーするわけではありません。continue
実行時にディスクリプタは反転しません。
また、どのように動作するか、実際にどのように動作するかを分析します。
GIT_INSTALLED=$?
$?
最後に実行されたコマンドの終了コード。デバッグを使用してこれをさらに詳しく見てください(set -x
)。
さらに、初心者は静的テストスクリプトによって大きな利点を得ることができます。shellcheck.net。