LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   cp exit status and conditional execution (https://www.linuxquestions.org/questions/programming-9/cp-exit-status-and-conditional-execution-4175511290/)

ThreeNine 07-16-2014 10:26 AM

cp exit status and conditional execution
 
Hi all,

I'm working on a Bash script for copying files and it's almost done, but I ran into a weird error. It's supposed to increment a "success" counter in the case, but the problem I have is that it seems to always think that it has succeeded. Here is the copy code below:

Code:

cp $mPoint$UT $mPoint$UT_bak 1>/dev/null 2>&1 && ((successA++)) || echo "$UT not found on $mPoint"
When I remove the "
Code:

1>/dev/null 2>&1
" the output from cp is "can't stat: no such file or directory" which is really weird because the copy did actually succeed.

I've tried a bunch of things with no success, like changing the && to an || (still somehow increments successA). Also tried changing it to successA = $successA + 1 and a few other versions.

Any help is greatly appreciated.

rknichols 07-16-2014 10:47 AM

Insert a "set -x" line just above that code and see what is actually being executed.

szboardstretcher 07-16-2014 10:51 AM

reverse the redirects?

Code:

cp $mPoint$UT $mPoint$UT_bak 2>&1 1>/dev/null && ((successA++)) || echo "$UT not found on $mPoint"

ThreeNine 07-16-2014 11:21 AM

set -x:

It executes the command I expect it to. Here's what I learned: I still had test files in one of the mounted partitions that I did not expect to have. I will remove them and continue the testing, I think this may have been my problem. Thank you for the suggestion.

I haven't tried reversing the redirects. Not sure what this would do, but removing them completely doesn't seem to help.

UPDATE:

I removed the test files, here's the output of set -x:
Code:

+ cp /mnt/sda1/file /mnt/sda1/file_bak
cp: can't stat '/mnt/sda1/file': No such file or directory
+ (( successA++ ))

It seems to increment the success counter despite failure!

suicidaleggroll 07-16-2014 11:21 AM

Are you sure you don't need some {} around your variable names?

From the looks of it, you have three variables at play here: $mPoint, $UT, and $UT_bak. Is that correct? Or is $UT_bak supposed to be ${UT}_bak?

ThreeNine 07-16-2014 11:44 AM

Yeah, there are three variables. Now that you mention it, ${UT}_bak might have been a more clever way of doing it. So now that I've resolved that there were test files in place I thought I had deleted (actually the program restored them), I can say that the
Code:

cp $mPoint$UT $mPoint$UT_bak 2>&1 1>/dev/null && ((successA++))
is working correctly, but that the
Code:

|| echo "$UT not found on $mPoint"
does not work as expected. (Executes either way). I could separate it out into an if statement easily enough, but it seems like I should be able to execute it depending on success of previous statements.

ntubski 07-16-2014 12:33 PM

That's because ((successA++)) is "failing":

Code:

$ successA=0 ; if ((successA++)) ; then echo success ; else echo failure ; fi
failure

That's because the post-increment returns the original value of successA which is 0, and for (()) 0 means false. You could use the pre-increment operator ((++successA)) or the comma operator ((successA++, 1)).

szboardstretcher 07-16-2014 12:36 PM

Unable to duplicate with simplification:

Code:

cp this that 1>/dev/null 2>&1 && echo GOOD: $? || echo BAD: $?
BAD: 1

What is the rest of the script concerning these variables?

NevemTeve 07-16-2014 12:55 PM

I'd try sg like this
Code:

if cp "$mPoint$UT" "$mPoint$UT_bak" 1>/dev/null 2>&1; then
    ((successA++))
else
    echo "$UT not found on $mPoint"
fi


ThreeNine 07-16-2014 02:23 PM

Quote:

Originally Posted by ntubski (Post 5204856)
That's because ((successA++)) is "failing":

Code:

$ successA=0 ; if ((successA++)) ; then echo success ; else echo failure ; fi
failure

That's because the post-increment returns the original value of successA which is 0, and for (()) 0 means false. You could use the pre-increment operator ((++successA)) or the comma operator ((successA++, 1)).

Perfect! ((successA++,1) is exactly what I needed. Thank you!


All times are GMT -5. The time now is 11:27 PM.