test.sh and ROD redirection
Hi!
As I've been doing last minute fixes to shell testcases I've stambled upon this problem. We have a couple of places that do:
ROD echo foo > bar
And while this works fine if the command executes successfully it writes the error message to the file bar on failure as well (since the part that gets to the ROD as $@ is the 'echo foo' while the '> bar' is parsed by the shell.
One solution would be redirecting the messages from tst_* to stderr, so we would be able to at least see the error message, but this wouldn't catch errors when we cannot write to the 'bar' (since echo foo would executed successfully anyway).
Another solution would be to create ROD_ECHO and ROD_CAT and change ROD to abort if anybody tries to use it with these two. Which solves our usage pattern but this is clumsy and still broken as anyone can redirect output from ROD anyway.
Is there a elegant solution to this problem that I'm missing?
Signature · 2 lines
Cyril Hrubis [email protected]
Hi,
Quoted 11 lines · Cyril Hrubis
Hi!
As I've been doing last minute fixes to shell testcases I've stambled upon this problem. We have a couple of places that do:ROD echo foo > bar
And while this works fine if the command executes successfully it writes the error message to the file bar on failure as well (since the part that gets to the ROD as $@ is the 'echo foo' while the '> bar' is parsed by the shell.
Quoted 4 lines
One solution would be redirecting the messages from tst_* to stderr, so we would be able to at least see the error message, but this wouldn't catch errors when we cannot write to the 'bar' (since echo foo would executed successfully anyway).
This won't work in case of simple file creation: ROD >file. Quotation marks seem to
help in this case with ROD.
./testcases/network/nfs/nfs_stress/nfs03: ROD >file$j$k
can be changed to ROD ">file$j$k"
Quoted 4 lines
Another solution would be to create
ROD_ECHOandROD_CATand change ROD to abort if anybody tries to use it with these two. Which solves our usage pattern but this is clumsy and still broken as anyone can redirect output from ROD anyway.
Could be just one ROD_RED that accepts parameters in this way: 1st for exec and
the others to set after '>' redirection.
ROD_RED()
{
$1 > ${@:2}
if [ $? -ne 0 ]; then
....
}ROD_RED "echo 0" "file"
Best regards,
Alexey
Quoted 2 lines
Is there a elegant solution to this problem that I'm missing?
Hi!
Quoted 14 lines
Quoted 10 lines
As I've been doing last minute fixes to shell testcases I've stambled upon this problem. We have a couple of places that do:
ROD echo foo > bar
And while this works fine if the command executes successfully it writes the error message to the file bar on failure as well (since the part that gets to the ROD as $@ is the 'echo foo' while the '> bar' is parsed by the shell.
Quoted 4 lines
One solution would be redirecting the messages from tst_* to stderr, so we would be able to at least see the error message, but this wouldn't catch errors when we cannot write to the 'bar' (since echo foo would executed successfully anyway).
Quoted 6 lines
This won't work in case of simple file creation: ROD >file. Quotation marks seem to help in this case with ROD.
./testcases/network/nfs/nfs_stress/nfs03: ROD >file$j$k
can be changed to ROD ">file$j$k"
You lost me here. All I wanted to do is:
testcases/lib/test.sh +1 -1
@@ -47,7 +47,7 @@ tst_resm() local ret=$1 shift - echo "$TCID $TST_COUNT $ret : $@" + echo "$TCID $TST_COUNT $ret : $@" >&2
This should not break anything. And maybe this is a good idea regardless the original problem.
Quoted 9 lines
Quoted 4 lines
Another solution would be to create
ROD_ECHOandROD_CATand change ROD to abort if anybody tries to use it with these two. Which solves our usage pattern but this is clumsy and still broken as anyone can redirect output from ROD anyway.Could be just one
ROD_REDthat accepts parameters in this way: 1st for exec and
the others to set after '>' redirection.
Quoted 8 lines
ROD_RED(){ $1 > ${@:2} if [ $? -ne 0 ]; then .... }
ROD_RED"echo 0" "file"
This sounds good, but I would like to have the file as single argument so that we do not have to quote the command in question. The easiest solution would be to have the file to be the first argument, but that is counter intuitive, so I would rather go with the last even if the code ends up far more complicated.
Another option would be inventing our special syntax for redirecting for ROD. Use for example % and threat it like > i.e. split $@ on % and redirect the output to whatever is found after % which shouldn't be much more complicated than separating last parameter from $@...
Signature · 2 lines
Cyril Hrubis [email protected]
Hi!
Quoted 4 lines
Another option would be inventing our special syntax for redirecting for ROD. Use for example % and threat it like > i.e. split $@ on % and redirect the output to whatever is found after % which shouldn't be much more complicated than separating last parameter from $@...
What about this one:
testcases/lib/test.sh +23 -1
@@ -214,7 +214,29 @@ ROD_SILENT() ROD() { - $@ + local cmd + local arg + local file + local flag + + for arg; do + if [ "$arg" == ">" ]; then + flag=1 + continue + fi + + if [ -n "$flag" ]; then + break + fi + cmd="$cmd $arg" + done + + if [ -n "$flag" ]; then + $cmd > $arg + else + $@ + fi + if [ $? -ne 0 ]; then tst_brkm TBROK "$@ failed" fi
It's called as: 'ROD echo a \> b', the reason for choosing \> is that the error message will contain '>' instead of some strange char as %.
I.e. doing 'ROD echo a \> /proc/cpuinfo' yields:
test.sh: line 235: /proc/cpuinfo: Permission denied foo 1 TBROK : echo b > /proc/cpuinfo failed
Signature · 2 lines
Cyril Hrubis [email protected]
Hi,
Quoted 13 lines · Cyril Hrubis
Hi!
Quoted 4 lines
Another option would be inventing our special syntax for redirecting for ROD. Use for example % and threat it like > i.e. split $@ on % and redirect the output to whatever is found after % which shouldn't be much more complicated than separating last parameter from $@...
What about this one:
testcases/lib/test.sh +0
-0@@ -214,7 +214,29 @@ ROD_SILENT()
testcases/lib/test.sh ROD_SILENT() · line 223
Quoted 10 lines
testcases/lib/test.sh +7
-1ROD() { - $@ + local cmd + local arg + local file + local flag + + for arg; do + if [ "$arg" == ">" ]; then
I would change it to
if [ "${arg:0:1}" == ">" ]; then
arg=${arg:1}in case '\>' is not separated by space.
e.g.:
ROD echo a \>/proc/cpuinfo
testcases/lib/test.sh ROD_SILENT() · line 225
Quoted 2 lines
testcases/lib/test.sh +2
-0+ flag=1 + continue
May be break here, so we don't need the next if block.
testcases/lib/test.sh ROD_SILENT() · line 231
Quoted 6 lines
testcases/lib/test.sh +6
-0+ fi + + if [ -n "$flag" ]; then + break + fi + cmd="$cmd $arg"
But what if the rest of args has something else, e.g. 2>&1 ?
Quoted 13 lines
testcases/lib/test.sh +8
-0+ done + + if [ -n "$flag" ]; then + $cmd > $arg + else + $@ + fi + if [ $? -ne 0 ]; then tst_brkm TBROK "$@ failed" fi
Quoted 7 lines
It's called as: 'ROD echo a \> b', the reason for choosing \> is that the error message will contain '>' instead of some strange char as %.
I.e. doing 'ROD echo a \>
/proc/cpuinfo' yields:
test.sh: line 235:/proc/cpuinfo: Permission denied foo 1 TBROK : echo b >/proc/cpuinfofailed
Best regards,
Alexey
Hi!
Quoted 6 lines
testcases/lib/test.sh ROD_SILENT() · line 223
Quoted 2 lines
testcases/lib/test.sh +2
-0+ for arg; do + if [ "$arg" == ">" ]; thenI would change it to
if [ "${arg:0:1}" == ">" ]; then arg=${arg:1}
That does work only in bash.
The easiest portable way I can come up with is:
if [ "${arg#\>}" != "$arg" ]; then
arg=${arg#\>}
fiQuoted 3 lines
testcases/lib/test.sh ROD_SILENT() · line 225
Quoted 2 lines
testcases/lib/test.sh +2
-0+ flag=1 + continueMay be break here, so we don't need the next if block.
Right.
Quoted 8 lines
testcases/lib/test.sh ROD_SILENT() · line 231
Quoted 6 lines
testcases/lib/test.sh +6
-0+ fi + + if [ -n "$flag" ]; then + break + fi + cmd="$cmd $arg"But what if the rest of args has something else, e.g. 2>&1 ?
Hmm, we can look for that in the $@ as well but nobody is using ROD with that at the moment. We can think about this later ideally when there is need for this.
Signature · 2 lines
Cyril Hrubis [email protected]
Hi!
Quoted 3 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ flag=1 + continueMay be break here, so we don't need the next if block.
We have to do another loop just to fetch the parameter after the \> if there is space between \> and path. So the continue should stay.
Full version then would be:
testcases/lib/test.sh +29 -1
@@ -214,7 +214,35 @@ ROD_SILENT() ROD() { - $@ + local cmd + local arg + local file + local flag + + for arg; do + file="${arg#\>}" + if [ "$file" != "$arg" ]; then + if [ -n "$file" ]; then + break + fi + flag=1 + continue + fi + + if [ -n "$flag" ]; then + file="$arg" + break + fi + + cmd="$cmd $arg" + done + + if [ -n "$file" ]; then + $cmd > $file + else + $@ + fi + if [ $? -ne 0 ]; then tst_brkm TBROK "$@ failed" fi
This works both with:
ROD echo a \> file
ROD echo a \>file
Signature · 2 lines
Cyril Hrubis [email protected]
Quoted 7 lines · Cyril Hrubis
...
This works both with:
ROD echo a \> file
ROD echo a \>file
Looks good to me!
Best regards,
Alexey
Hi!
Quoted 1 line
Looks good to me!
Ok. I will push this along with documentation and fixed all uses in tests tomorrow, then tag the release.
Signature · 2 lines
Cyril Hrubis [email protected]