试图了解Bash中`test <command />`的行为

时间:2018-07-15 20:10:46

标签: bash

假设我有一个简单的C程序(test.c):

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
     exit (1);
}

很明显,该程序的退出代码为1:

$ gcc test.c
$ ./a.out
$ echo $?
1

但是当我运行test ./a.out时,测试结果与退出代码不匹配:

$ test ./a.out
$ echo $?
0

那么实际正在测试什么?为什么测试结果为0?

2 个答案:

答案 0 :(得分:4)

test是Bash内置的,通常由备用名称[调用。

最后一条命令(test ./a.out)的状态为0,表示成功,因为test ./a.out检查./a.out作为字符串是否包含一个或多个字符(不是空字符串),并且因为它不是一个空字符串,所以返回成功或0。test ./a.out命令行不会执行您的a.out程序,就像从程序中打印内容一样。

按照书面规定,您的程序不需要<stdio.h>标头或main()的参数-它应该是int main(void)。如果您使用<stdlib.h>而不是return 1;,也可能会丢失exit(1);

int main(void)
{
    return 1;
}

要在外壳中的if状态下使用退出状态,只需直接使用它即可:

if ./a.out ; then
    echo Success
else
    echo Failure
fi

经验法则:请勿调用C程序test,因为您迟早会感到困惑-通常早晚会困惑。

答案 1 :(得分:3)

  1. 您的C程序将“ 1”返回到外壳程序(与“ exit()”相比,我更喜欢“ return()”,但是...)

  2. 如果要与“ * nix”测试命令一起实际运行“ a.out”,则可以使用以下语法:

    `./a.out` # classic *nix
    

    $(./a.out) # Bash
    
  3. 但是,如果执行此操作,则“ test”将读取打印到“ stdout”的值,并且 NOT 退出时程序返回的值。

  4. 您可以在此处阅读有关test的更多信息:

  5. 这里是一个示例:

C程序:

#include <stdio.h>

int main (int argc, char *argv[]) {
  printf("%d\n", argc);
  return 2;
}

Shell脚本:

echo "Assign RETVAL the return value of a.out:"
./a.out RETVAL=$? echo " " RETVAL=$RETVAL

echo "Assign RETVAL the value printed to stdout by a.out:"
RETVAL=$(./a.out) echo " " RETVAL=$RETVAL

echo "Turn an 'trace' and run a.out with 'test':" 
set -x 
if [ $(./a.out) -eq 1 ]; then
  echo "One" 
else
  echo "Not One"
fi

示例输出:

paulsm@vps2:~$ ./tmp.sh
Assign RETVAL the return value of a.out:
1
  RETVAL=2
Assign RETVAL the value printed to stdout by a.out:
  RETVAL=1
Turn an 'trace' and run a.out with 'test':
+++ ./a.out
++ '[' 1 -eq 1 ']'
++ echo One
One

也:

已经提到的几点:

a。通常,return 1exit (1)更好。

b。 “ test”可能不是可执行文件的好名字-因为它与内置的“ test”命令冲突。像“ test_return”之类的东西可能是更好的选择。