402

が真でないechoときにコマンドを実行してもらいたいのですが。cat /etc/passwd | grep "sysa"

私は何が間違っているのですか?

if ! [ $(cat /etc/passwd | grep "sysa") ]; then
        echo "ERROR - The user sysa could not be looked up"
        exit 2
fi
4

7 に答える 7

559

試す

if ! grep -q sysa /etc/passwd ; then

greptrue検索ターゲットが見つかった場合と見つからなかった場合に戻りますfalse

したがって、NOT false== true

ifシェルでの評価は非常に柔軟になるように設計されており、多くの場合、コマンドのチェーンを必要としません(あなたが書いたように)。

また、コードをそのまま見て、$( ... )cmd-substitutionの形式を使用することは称賛されるべきですが、プロセスから何が出てくるかを考えてください。echo $(cat /etc/passwd | grep "sysa")私が何を意味するのか見てみてください。-c(count)オプションを使用してgrepを実行し、どちらが機能するかを実行することで、それをさらに進めることができますが、if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; thenかなり古い学校です。

ただし、次のような最新のシェル機能(算術評価)を使用できます。

if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`

これにより、c-langベースの比較演算子、==,<,>,>=,<=,%およびおそらく他のいくつかの演算子を使用できるという利点もあります。

この場合、Orwellophileのコメントによると、算術評価は次のようにさらに削減できます。

if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....

また

if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....

最後に、と呼ばれるUseless Use of Cat (UUOC)があります。:-)何人かの人々は上下にジャンプして、ゴスカを泣きます!cmd行にファイル名を付けることができるとだけ言っておきますがgrep、必要がないのになぜ追加のプロセスとパイプ構造を呼び出すのですか?;-)

これがお役に立てば幸いです。

于 2012-05-11T13:54:59.420 に答える
38

私はそれを次のように単純化できると思います:

grep sysa /etc/passwd || {
    echo "ERROR - The user sysa could not be looked up"
    exit 2
}

または単一のコマンドラインで

$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }

于 2012-05-13T15:05:26.347 に答える
18

これです

if [[ !  $(cat /etc/passwd | grep "sysa") ]]
Then echo " something"
exit 2
fi
于 2020-09-17T02:46:38.373 に答える
10

私は何が間違っているのですか?

$(...)終了ステータスではなく値を保持するため、このアプローチは間違っています。ただし、この特定のケースでsysaは、テストステートメントを実現するために印刷されるため、実際に機能します。ただし、コマンドはstdoutに何も書き込まないため(終了コードが0であっても)、常にif ! [ $(true) ]; then echo false; fi出力されます。そのため、に言い換える必要があります。falsetrueif ! grep ...; then

別の方法はですcat /etc/passwd | grep "sysa" || echo error。編集:アレックスが指摘したように、猫はここでは役に立たないgrep "sysa" /etc/passwd || echo error

他の答えはかなり紛らわしいと思いました。これが誰かに役立つことを願っています。

于 2017-09-02T18:38:16.767 に答える
3

例として、これが答えです。

データロガーがオンラインであることを確認するためにcron、次のようなスクリプトが15分ごとに実行されます。

#!/bin/bash
#
if ! ping -c 1 SOLAR &>/dev/null
then
  echo "SUBJECT:  SOLAR is not responding to ping" | ssmtp abc@def.com
  echo "SOLAR is not responding to ping" | ssmtp 4151112222@txt.att.com
else
  echo "SOLAR is up"
fi
#
if ! ping -c 1 OUTSIDE &>/dev/null
then
  echo "SUBJECT:  OUTSIDE is not responding to ping" | ssmtp abc@def.com
  echo "OUTSIDE is not responding to ping" | ssmtp 4151112222@txt.att.com
else
  echo "OUTSIDE is up"
fi
#

... http: //www.SDsolarBlog.com/montageのモンタージュで見ることができる各データロガーについても同様です。


参考までに、を使用&>/dev/nullすると、エラーを含むコマンドからのすべての出力がにリダイレクトされます/dev/null

(条件付きで必要なのexit statuspingコマンドのみです)

cronまた、参考までに、ジョブはスクリプトで使用するroot必要がないため、実行されることに注意してください。sudo pingcron

于 2017-11-08T16:07:29.367 に答える
2

それをサポートするUnixシステム(macOSではないようです):

if getent passwd "$username" >/dev/null; then
    printf 'User %s exists\n' "$username"
else
    printf 'User %s does not exist\n' "$username"
fi 

これには、使用中の可能性のあるすべてのディレクトリサービス(YP / NISまたはLDAPなど)とローカルパスワードデータベースファイルを照会するという利点があります。


の問題grep -q "$username" /etc/passwdは、そのようなユーザーがいない場合に誤検知が発生することですが、他の何かがパターンに一致します。これは、ファイルのどこかに部分的または完全に一致する場合に発生する可能性があります。

たとえば、私のpasswdファイルには、次のような行があります

build:*:21:21:base and xenocara build:/var/empty:/bin/ksh

これにより、私のシステムにそのようなユーザーがいない場合でも、などcaraの有効な一致が引き起こされます。enoc

正しい解決策を得るには、ファイルgrepを適切に解析する必要があります。/etc/passwd

if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
    # found
else
    # not found
fi

:...または最初の-delimitedフィールドに対する他の同様のテスト。

于 2017-09-02T18:46:13.160 に答える
0

単に:

if ! examplecommand arg1 arg2 ...; then
    #code block
fi

角かっこなし。

于 2022-02-01T13:23:24.617 に答える