LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-16-2014, 10:26 AM   #1
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Rep: Reputation: Disabled
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.
 
Old 07-16-2014, 10:47 AM   #2
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,770

Rep: Reputation: 2210Reputation: 2210Reputation: 2210Reputation: 2210Reputation: 2210Reputation: 2210Reputation: 2210Reputation: 2210Reputation: 2210Reputation: 2210Reputation: 2210
Insert a "set -x" line just above that code and see what is actually being executed.
 
1 members found this post helpful.
Old 07-16-2014, 10:51 AM   #3
szboardstretcher
Senior Member
 
Registered: Aug 2006
Location: Detroit, MI
Distribution: GNU/Linux systemd
Posts: 4,278

Rep: Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694
reverse the redirects?

Code:
cp $mPoint$UT $mPoint$UT_bak 2>&1 1>/dev/null && ((successA++)) || echo "$UT not found on $mPoint"
 
Old 07-16-2014, 11:21 AM   #4
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
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!

Last edited by ThreeNine; 07-16-2014 at 11:29 AM.
 
Old 07-16-2014, 11:21 AM   #5
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
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?
 
Old 07-16-2014, 11:44 AM   #6
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
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.
 
Old 07-16-2014, 12:33 PM   #7
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,774

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
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)).

Last edited by ntubski; 07-16-2014 at 12:34 PM. Reason: make example repeatable by adding successA=0 ;
 
Old 07-16-2014, 12:36 PM   #8
szboardstretcher
Senior Member
 
Registered: Aug 2006
Location: Detroit, MI
Distribution: GNU/Linux systemd
Posts: 4,278

Rep: Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694
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?
 
Old 07-16-2014, 12:55 PM   #9
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,852
Blog Entries: 1

Rep: Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868
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
 
1 members found this post helpful.
Old 07-16-2014, 02:23 PM   #10
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by ntubski View Post
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!
 
  


Reply

Tags
bash


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] command do not exit successfully after execution. Satyaveer Arya Linux - Software 12 08-27-2012 09:01 AM
[SOLVED] How to do conditional execution in makefile? nachiket_linux Programming 3 11-24-2011 11:55 PM
PHP & HTML conditional execution question bostonantifan Programming 1 05-19-2009 07:32 AM
conditional execution tostay2003 Programming 5 12-28-2007 03:01 PM
exit status naflan Programming 2 10-22-2004 12:22 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:48 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration