gpt4 book ai didi

shell - 如何否定进程的返回值?

转载 作者:行者123 更新时间:2023-12-03 05:08:06 25 4
gpt4 key购买 nike

我正在寻找一个简单但跨平台的否定流程,它可以否定流程返回的值。它应该将 0 映射到某个值 != 0 并将任何值 != 0 映射到 0,即以下命令应返回“yes,nonexistingpath 不存在”:

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

这个! - 运算符很棒,但不幸的是它不独立于 shell。

最佳答案

以前,答案是通过现在的第一部分作为最后一部分来呈现的。

POSIX Shell 包含 ! 运算符

在研究 shell 规范的其他问题时,我最近(2015 年 9 月)注意到 POSIX shell 支持 ! 运算符。例如,它被列为 reserved word并且可以出现在 pipeline 的开头— 其中简单命令是“管道”的特殊情况。因此,它也可以在 POSIX 兼容 shell 中的 if 语句和 whileuntil 循环中使用。因此,尽管我有所保留,但它的使用范围可能比我在 2008 年意识到的更广泛。快速检查 POSIX 2004 和 SUS/POSIX 1997 表明 ! 在这两个版本中都存在。

请注意,! 运算符必须出现在管道的开头,并对整个管道的状态代码(即最后命令)。以下是一些示例。

# 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

可移植答案 - 适用于古董 shell

在 Bourne(Korn、POSIX、Bash)脚本中,我使用:

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

这是尽可能便携的。 “命令和参数”可以是管道或其他复合命令序列。

not 命令

“!”操作符,无论是内置到 shell 中还是由操作系统提供,都不是普遍可用的。不过,编写起来并不难 - 下面的代码至少可以追溯到 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"' 中的代码提供了简单的错误报告功能 - 我在任何地方都使用它。根据要求提供源代码 - 请参阅我的个人资料页面与我联系。

关于shell - 如何否定进程的返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/367069/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com