如何取消流程的返回值? [英] How can I negate the return-value of a process?

查看:114
本文介绍了如何取消流程的返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个简单但跨平台的 negate 流程,该流程可以抵消流程返回的值。它应该将0映射到某个值!= 0,将任何值!= 0映射到0,即以下命令应返回是,不存在路径:

I'm looking for a simple, but cross-platform negate-process that negates the value a process returns. It should map 0 to some value != 0 and any value != 0 to 0, i.e. the following command should return "yes, nonexistingpath doesn't exist":

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

推荐答案

以前,答案是用什么表示的?

在探索其他问题的外壳规范时,我最近(2015年9月)注意到POSIX外壳支持运算符。例如,它被列为保留字,并且可以出现在管道的开头,其中一个简单的命令是管道的特殊情况。因此,如果语句和 while 直到也会循环-在POSIX兼容的shell中。因此,尽管我有所保留,但它的可用范围可能比我在2008年时意识到的要广泛。对POSIX 2004和SUS / POSIX 1997的快速检查显示,两个目录中都存在

Poking around the shell specification for other issues, I recently (September 2015) noticed that the POSIX shell supports a ! operator. For example, it is listed as a reserved word and can appear at the start of a pipeline — where a simple command is a special case of 'pipeline'. It can, therefore, be used in if statements and while or until loops too — in POSIX-compliant shells. Consequently, despite my reservations, it is probably more widely available than I realized back in 2008. A quick check of POSIX 2004 and SUS/POSIX 1997 shows that ! was present in both those versions.

请注意,运算符必须出现在管道并否定整个管道的状态代码(即 last 命令)。以下是一些示例。

Note that the ! operator must appear at the beginning of the pipeline and negates the status code of the entire pipeline (i.e. the last command). Here are some examples.

# 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)脚本中,我使用:

Portable answer — works with antique shells

In a Bourne (Korn, POSIX, Bash) script, I use:

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

这是随身携带的。 命令和参数可以是管道或其他复合命令序列。

This is as portable as it gets. The 'command and arguments' can be a pipeline or other compound sequence of commands.

无论是内置在shell中还是由操作系统提供的'!'运算符都不是通用的。不过,编写该代码并不可怕-下面的代码至少可以追溯到1991年(尽管我认为我是在更早的时候才编写以前的版本的)。不过,我不太倾向于在脚本中使用它,因为它不能可靠地使用。

The '!' operator, whether built-in to your shell or provided by the o/s, is not universally available. It isn't dreadfully hard to write, though - the code below dates back to at least 1991 (though I think I wrote a previous version even longer ago). I don't tend to use this in my scripts, though, because it is not reliably available.

/*
@(#)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 中的代码提供了简单的错误报告功能-我到处都在使用它。根据要求提供源代码-请参阅我的个人资料页面与我联系。

This returns 'success', the opposite of failure, when it fails to execute the command. We can debate whether the 'do nothing successfully' option was correct; maybe it should report an error when it isn't asked to do anything. The code in '"stderr.h"' provides simple error reporting facilities - I use it everywhere. Source code on request - see my profile page to contact me.

这篇关于如何取消流程的返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆