在具有相同输入的两个程序上差异?

时间:2011-10-02 00:09:49

标签: shell sh

#!bin/sh

i=0;
while read inputline
do
        array[$i]=$inputline;
        i=`expr $i + 1`
done

j=i;

./a.out > test/temp;
while [$i -gt 0]
do
echo ${array[$i]}
i=`expr $i -  1`;
done

./test > test/temp1;
while [$j -gt 0]
do
echo ${array[$j]}
j=`expr $j -  1`;
done

diff test/temp1 test/temp

上述代码有什么问题?本质上它的意思是从stdin获取一些输入,然后向两个单独的程序提供相同的输入,然后将它们的输出放入另一个文件然后区分它们。怎么会不起作用?

4 个答案:

答案 0 :(得分:1)

我看到一些可能存在问题的事情。

首先,通常sh的路径是/ bin / sh。我希望shebang系列是这样的:

#!/bin/sh

但是,如果您在命令行上调用sh,则可能不会导致错误。

其次,while循环的输出需要重定向到可执行文件:

{
    while [ $i -lt $lines ]
    do
        echo ${array[$i]}
        i=`expr $i +  1`;
    done
} | ./a.out > test/temp;

注意:我在Mac OS X和Linux上对此进行了测试,并且sh在两个操作系统上都是bash的别名。我并不完全确定这个结构能够在普通的旧版本中运行。

第三,你的while循环中的索引是关闭的:它应该从0到$ i - 1(或从$ i - 1到0)。如您的示例所示,它从$ i变为1.

最后,“test”用作可执行文件名和输出目录名。这就是我最终的结果:

#!/bin/sh

lines=0;
while read inputline
do
        array[$lines]=$inputline;
        lines=`expr $lines + 1`
done

i=0
{
    while [ $i -lt $lines ]
    do
        echo ${array[$i]}
        i=`expr $i +  1`;
    done
} | ./a.out > test/temp;

i=0
{
    while [ $i -lt $lines ]
    do
        echo ${array[$i]}
        i=`expr $i +  1`;
    done
} | ./b.out > test/temp1;

diff test/temp1 test/temp

另一种做你想做的事情的方法是将测试输入存储在一个文件中,然后使用管道将输入提供给程序。例如,如果您的输入存储在input.txt中,则可以执行以下操作:

cat input.txt | a.out > test/temp
cat input.txt | b.out > test/temp1
diff test/temp test/temp1

答案 1 :(得分:1)

另一种方法是捕获这样的stdin:

#!/bin/sh
input=$(cat -)
printf "%s" "$input" | ./a.out > test/temp
printf "%s" "$input" | ./test  > test/temp1
diff test/temp test/temp1

或者,使用bash进程替换和here-strings:

#!/bin/bash
input=$(cat -)
diff <(./a.out <<< "$input") <(./test <<< "$input")

答案 2 :(得分:1)

怎么了?

分号不是必需的,尽管它们没有伤害。

初始输入循环看起来没问题。

作业j=ij=$i完全不同。

您运行程序./a.out而不向其提供任何输入。

然后你有一个循环,旨在回应输入。与读取方式相比,它向后提供输入。

你重复./test的程序执行而不提供任何输入,然后是一个用于回显输入的重复循环,但是这个因为错误分配而失败。

然后对不确定输入产生的两个输出运行diff

您不会清理临时文件。

怎么做

这个脚本很简单 - 除了它确保清理临时文件。

tmp=${TMPDIR:-/tmp}/tester.$$
trap "rm -f $tmp.?; exit 1" 0 1 2 3 13 15

cat - > $tmp.1
./a.out < $tmp.1 > $tmp.2
./test  < $tmp.1 > $tmp.3
diff $tmp.2 $tmp.3

rm -f $tmp.?
trap 0
exit 0

第一步是捕获文件$tmp.1中的输入。然后运行两个测试程序,捕获文件$tmp.2$tmp.3中的输出。然后取两个文件的区别。

第一个trap行确保在shell退出时删除临时文件,或者它从集合{HUP,INT,QUIT,PIPE,TERM}接收信号。第二行trap行取消“退出”陷阱,以便脚本可以成功退出。 (您可以通过捕获其退出状态diff然后使用status=$?exit $status的退出状态转发给调用程序(shell)。)

答案 3 :(得分:0)

如果您只想为两个程序提供相同的stdin,那么您可能希望将进程替换tee一起使用。假设您可以cat从文件中输入您的输入(或者仅使用tee部分,如果您希望它是交互式的),您可以使用以下内容:

cat input | tee >(./p1 > p1.out) >(./p2 > p2.out) && diff p1.out p2.out