I am trying to learn bashing. I am trying to run ./test testcase
the file in test case has the arguments 9 11 22 13, 32 35 32 16 on the next line and so on
My program takes 4 arguments. Right now if testcase has one line of arguments i.e 3 5 6 7 it works fine, but when there is more than 2 it can't run the program properly. I know I need a while loop to read each line of the file, but I am stuck here. If someone could help me it would be greatly appreciated. Thank you in advance.
I've asked this question here before, I don't know if everyone is too busy or don't know how. Thanks again
your_path=../test/test
test_path=../../public/test
file_input="$1"
#while read -r line; do
#done < "$file_input"
# Read contents in the file
contents=$(< "$file_input")
# Display output of the test file
"$test_path" $contents > correctanswer 2>&1
# Display output of your file
"$your_path" $contents > youranswer 2>&1
diff the solutions
diff correctanswer youranswer > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "The two outputs were exactly the same "
else
echo "$divider"
echo "The two outputs were different "
diff youranswer correctanswer
echo "Do you wish to see the ouputs side-by-side?"
select yn in "Yes" "No"; do
case $yn in
Yes ) echo "LEFT: Your Output RIGHT: Solution Output"
sleep 1
vimdiff youranswer correctanswer; break;;
No ) exit;;
esac
done
fi
I would normally use a construct similar to the following (applying to your example). Note that the only change your need to make is the cat $file | (while read l; do
and then done)
that closes the cycle. The body of the cycle is exactly your code with exception that contents
is replaced with l
(line read). Parenthesis around the cycle actually launch another instance of the shell where while is executed and its stdin
is set to be fed from cat
.
your_path=../test/test
test_path=../../public/test
file_input="$1"
exec 3< $file_input
while read -u 3 l; do
# do your per-test diffs and outputs here
# variable $l will contain one line of $file_input
# Display output of the test file
"$test_path" $l > correctanswer 2>&1
# Display output of your file
"$your_path" $l > youranswer 2>&1
# diff the solutions
diff correctanswer youranswer > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "The two outputs were exactly the same "
else
echo "$divider"
echo "The two outputs were different "
diff youranswer correctanswer
echo "Do you wish to see the ouputs side-by-side?"
select yn in "Yes" "No"; do
case $yn in
Yes ) echo "LEFT: Your Output RIGHT: Solution Output"
sleep 1
vimdiff youranswer correctanswer; break;;
No ) exit;;
esac
done
fi
done
I think you can do it like this:
your_path=../test/test
test_path=../../public/test
file_input="$1"
while read -r -u 3 contents
do
# Display output of the test file
"$test_path" $contents > correctanswer 2>&1
# Display output of your file
"$your_path" $contents > youranswer 2>&1
# diff the solutions
diff correctanswer youranswer > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "The two outputs were exactly the same "
else
echo "$divider"
echo "The two outputs were different "
diff youranswer correctanswer
echo "Do you wish to see the ouputs side-by-side?"
select yn in "Yes" "No"; do
case $yn in
Yes) echo "LEFT: Your Output RIGHT: Solution Output"
sleep 1
vimdiff youranswer correctanswer
break;;
No) exit;;
esac
done
fi
done 3< "$file_input"
Modified so that the read
command reads on file descriptor 3, leaving standard input available for the select
, etc.
I don't know what you're doing that makes it fail. I created two programs, test1
and test2
. Initially, they were identical:
printf "%s\n" "$@"
Then I changed test2
so it contained:
printf "%s\n" "1$@2"
With this data in input.file
:
9 11 22 13
2 35 32 16
I ran the script botched.sh
:
$ bash -x botched.sh input.file
+ '[' -f /etc/bashrc ']'
+ . /etc/bashrc
++ '[' -z '' ']'
++ return
+ alias 'r=fc -e -'
+ your_path=./test1
+ test_path=./test2
+ file_input=input.file
+ read -r -u 3 contents
+ ./test2 9 11 22 13
+ ./test1 9 11 22 13
+ diff correctanswer youranswer
+ '[' 0 -eq 0 ']'
+ echo 'The two outputs were exactly the same '
The two outputs were exactly the same
+ read -r -u 3 contents
+ ./test2 2 35 32 16
+ ./test1 2 35 32 16
+ diff correctanswer youranswer
+ '[' 0 -eq 0 ']'
+ echo 'The two outputs were exactly the same '
The two outputs were exactly the same
+ read -r -u 3 contents
$
The outputs were recognized as identical, as you'd expect. Then with the modified test2
, I reran it:
$ bash -x botched.sh input.file
+ '[' -f /etc/bashrc ']'
+ . /etc/bashrc
++ '[' -z '' ']'
++ return
+ alias 'r=fc -e -'
+ your_path=./test1
+ test_path=./test2
+ file_input=input.file
+ read -r -u 3 contents
+ ./test2 9 11 22 13
+ ./test1 9 11 22 13
+ diff correctanswer youranswer
+ '[' 1 -eq 0 ']'
+ echo ''
+ echo 'The two outputs were different '
The two outputs were different
+ diff youranswer correctanswer
1c1
< 9
---
> 19
4c4
< 13
---
> 132
+ echo 'Do you wish to see the ouputs side-by-side?'
Do you wish to see the ouputs side-by-side?
+ select yn in '"Yes"' '"No"'
1) Yes
2) No
#? 1
+ case $yn in
+ echo 'LEFT: Your Output RIGHT: Solution Output'
LEFT: Your Output RIGHT: Solution Output
+ sleep 1
+ vimdiff youranswer correctanswer
2 files to edit
+ break
+ read -r -u 3 contents
+ ./test2 2 35 32 16
+ ./test1 2 35 32 16
+ diff correctanswer youranswer
+ '[' 1 -eq 0 ']'
+ echo ''
+ echo 'The two outputs were different '
The two outputs were different
+ diff youranswer correctanswer
1c1
< 2
---
> 12
4c4
< 16
---
> 162
+ echo 'Do you wish to see the ouputs side-by-side?'
Do you wish to see the ouputs side-by-side?
+ select yn in '"Yes"' '"No"'
1) Yes
2) No
#? 2
+ case $yn in
+ exit
$
The vimdiff
program did run and show the differences.
Note the basic debugging technique — running with bash -x
. It shows that the read is taking a single line of input with four numbers, and then those are passed to the surrogate programs test1
and test2
; then it takes a second line, and passes those to the surrogates programs.
Actual test code:
your_path=./test1 #../test/test
test_path=./test2 #../../public/test
file_input="$1"
while read -r -u 3 contents
do
# Display output of the test file
"$test_path" $contents > correctanswer 2>&1
# Display output of your file
"$your_path" $contents > youranswer 2>&1
# diff the solutions
diff correctanswer youranswer > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "The two outputs were exactly the same "
else
echo "$divider"
echo "The two outputs were different "
diff youranswer correctanswer
echo "Do you wish to see the ouputs side-by-side?"
select yn in "Yes" "No"; do
case $yn in
Yes) echo "LEFT: Your Output RIGHT: Solution Output"
sleep 1
vimdiff youranswer correctanswer
break;;
No) exit;;
esac
done
fi
done 3< "$file_input"
Tested with Bash 3.2.51 on Mac OS X 10.9.2.
If it doesn't work for you, then you need to set up surrogate test programs, similar to mine, and show what you get from running bash -x
on your script. You should also identify the platform you're running on and the version of Bash you are running.