diff на две программы с одинаковым вводом? - PullRequest
0 голосов
/ 02 октября 2011
#!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 ]

1 голос
/ 02 октября 2011

Другой подход заключается в захвате стандартного ввода, как это:

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

или, используя подстановку процесса bash и здесь-строки:

#!/bin/bash
input=$(cat -)
diff <(./a.out <<< "$input") <(./test <<< "$input")
1 голос
/ 02 октября 2011

Что не так?

Точки с запятой не нужны, хотя они не приносят вреда.

Начальный цикл ввода выглядит хорошо.

Назначение j=iотличается от j=$i.

Вы запускаете программу ./a.out, не предоставляя ей никакого ввода.

Затем у вас есть цикл, который должен был повторять ввод.Он обеспечивает ввод в обратном направлении по сравнению с тем, как он был прочитан.

Вы повторяете выполнение программы ./test без предоставления какого-либо ввода, после чего следует цикл повторения, который должен был повторить ввод, но этот не дает результатаиз-за неправильного назначения.

Затем вы запускаете diff на двух выходах, полученных из неопределенных входных данных.

Вы не очищаете временные файлы.

Как сделатьit

Этот скрипт прост - за исключением того, что он обеспечивает очистку временных файлов.

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 гарантирует, что временные файлы будут удалены при выходе из оболочки или при получении сигнала из набора {HUP, INT, QUIT, PIPE, СРОК }.Вторая строка trap отменяет ловушку 'exit', чтобы скрипт мог успешно завершиться.(Вы можете передать статус выхода diff вызывающей программе (оболочке), зафиксировав его статус выхода status=$? и затем используя exit $status.)

1 голос
/ 02 октября 2011

Я вижу несколько вещей, которые могут быть проблемами.

Во-первых, обычно путь к sh - это / bin / sh. Я ожидаю, что линия Шебанга будет примерно такой:

#!/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
0 голосов
/ 24 июня 2012

Если все, что вы хотите сделать, это предоставить один и тот же стандарт для двух программ, которые вы можете использовать процесс замены вместе с tee. Предполагая, что вы можете cat вводить данные из файла (или просто использовать часть tee, если хотите интерактивную иш), вы можете использовать что-то вроде этого:

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