124

プロセスが返す値を否定する、シンプルだがクロスプラットフォームの否定プロセスを探しています。0 を何らかの値 != 0 にマップし、任意の値 != 0 を 0 にマップする必要があります。つまり、次のコマンドは「はい、存在しないパスは存在しません」を返す必要があります。

 ls nonexistingpath | negate && echo "yes, nonexistingpath doesn't exist."

!- operator は優れていますが、残念ながらシェルに依存しません。

4

7 に答える 7

147

以前は、現在の最初のセクションが最後のセクションとして回答が提示されていました。

POSIX シェルには!演算子が含まれています

他の問題についてシェル仕様を調べていたところ、最近 (2015 年 9 月)、POSIX シェルが!オペレーターをサポートしていることに気付きました。たとえば、これは予約語としてリストされており、パイプラインの開始時に使用できます。単純なコマンドは「パイプライン」の特殊なケースです。したがって、POSIX準拠のシェルでは、ifステートメントwhileやループでも使用できます。untilしたがって、私の留保にもかかわらず、おそらく 2008 年に私が気付いていたよりも広く利用できるようになっているでしょう!

!演算子はパイプラインの先頭に表示する必要があり、パイプライン全体 (つまり、最後のコマンド)のステータス コードを無効にすることに注意してください。下記は用例です。

# Simple commands, pipes, and redirects work fine.
$ ! some-command succeed; echo $?
1
$ ! some-command fail | some-other-command fail; echo $?
0
$ ! some-command < succeed.txt; echo $?
1

# Environment variables also work, but must come after the !.
$ ! RESULT=fail some-command; echo $?
0

# A more complex example.
$ if ! some-command < input.txt | grep Success > /dev/null; then echo 'Failure!'; recover-command; mv input.txt input-failed.txt; fi
Failure!
$ ls *.txt
input-failed.txt

ポータブルな答え — アンティークのシェルで動作します

Bourne (Korn、POSIX、Bash) スクリプトでは、次を使用します。

if ...command and arguments...
then : it succeeded
else : it failed
fi

これは可能な限りポータブルです。「コマンドと引数」は、パイプラインまたはコマンドの他の複合シーケンスにすることができます。

notコマンド_

「!」シェルに組み込まれているか、o/s によって提供されているかに関係なく、operator はどこでも利用できるわけではありません。ただし、書くのはそれほど難しくありません。以下のコードは、少なくとも 1991 年にさかのぼります (以前のバージョンはもっと前に書いたと思いますが)。ただし、確実に利用できるわけではないため、スクリプトでこれを使用する傾向はありません。

/*
@(#)File:           $RCSfile: not.c,v $
@(#)Version:        $Revision: 4.2 $
@(#)Last changed:   $Date: 2005/06/22 19:44:07 $
@(#)Purpose:        Invert success/failure status of command
@(#)Author:         J Leffler
@(#)Copyright:      (C) JLSS 1991,1997,2005
*/

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "stderr.h"

#ifndef lint
static const char sccs[] = "@(#)$Id: not.c,v 4.2 2005/06/22 19:44:07 jleffler Exp $";
#endif

int main(int argc, char **argv)
{
    int             pid;
    int             corpse;
    int             status;

    err_setarg0(argv[0]);

    if (argc <= 1)
    {
            /* Nothing to execute. Nothing executed successfully. */
            /* Inverted exit condition is non-zero */
            exit(1);
    }

    if ((pid = fork()) < 0)
            err_syserr("failed to fork\n");

    if (pid == 0)
    {
            /* Child: execute command using PATH etc. */
            execvp(argv[1], &argv[1]);
            err_syserr("failed to execute command %s\n", argv[1]);
            /* NOTREACHED */
    }

    /* Parent */
    while ((corpse = wait(&status)) > 0)
    {
            if (corpse == pid)
            {
                    /* Status contains exit status of child. */
                    /* If exit status of child is zero, it succeeded, and we should
                       exit with a non-zero status */
                    /* If exit status of child is non-zero, if failed and we should
                       exit with zero status */
                    exit(status == 0);
                    /* NOTREACHED */
            }
    }

    /* Failed to receive notification of child's death -- assume it failed */
    return (0);
}

これは、コマンドの実行に失敗した場合、失敗の反対である「成功」を返します。「何もしない」オプションが正しかったかどうかは議論できます。何もするように求められていないときにエラーを報告する必要があるかもしれません。' ' 内のコードは、"stderr.h"単純なエラー報告機能を提供します。私はどこでも使用しています。リクエストに応じてソース コード - プロフィール ページを参照して連絡してください。

于 2008-12-14T23:40:01.133 に答える
46

Bash では、! コマンドの前に演算子。例えば:

! ls nonexistingpath && echo "yes, nonexistingpath doesn't exist"
于 2008-12-14T22:25:43.437 に答える
18

あなたは試すことができます:

ls nonexistingpath || echo "yes, nonexistingpath doesn't exist."

あるいは単に:

! ls nonexistingpath
于 2008-12-14T22:26:47.740 に答える
12

シェルとして Bash がない場合 (例: Git スクリプト、またはPuppet exec テスト)、以下を実行できます。

echo '! ls notexisting' | bash

-> 再コード: 0

echo '! ls /' | bash

-> 再コード: 1

于 2013-03-30T15:16:08.047 に答える
4
! ls nonexistingpath && echo "yes, nonexistingpath doesn't exist."

また

ls nonexistingpath || echo "yes, nonexistingpath doesn't exist."
于 2008-12-14T22:27:21.200 に答える