LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 05-13-2021, 09:50 AM   #1
centguy
Member
 
Registered: Feb 2008
Posts: 589
Blog Entries: 1

Rep: Reputation: 45
why won't if [ ! cmp -s A B ] work?


I think in bash,
this works.

Code:
if ! cmp -s A B;
then
  echo A and B are different
fi
Strangely enough
this won't work


Code:
if [ ! cmp -s A B ]; then
then
  echo A and B are different
fi
it says too many arguments.

Last edited by centguy; 05-15-2021 at 03:55 AM.
 
Old 05-13-2021, 10:01 AM   #2
EdGr
Member
 
Registered: Dec 2010
Location: California, USA
Distribution: I run my own OS
Posts: 920

Rep: Reputation: 442Reputation: 442Reputation: 442Reputation: 442Reputation: 442
The second example has the word "then" twice.
Ed
 
Old 05-13-2021, 10:54 AM   #3
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,135

Rep: Reputation: 2228Reputation: 2228Reputation: 2228Reputation: 2228Reputation: 2228Reputation: 2228Reputation: 2228Reputation: 2228Reputation: 2228Reputation: 2228Reputation: 2228

Always post the actual commands being entered and exact error messages. (i.e. copy and paste both of them.)

"[" is an alias for "test", which deals with expressions.
"if" does not deal with expressions, it deals with commands.
"!" happens to be valid syntax both before test expressions and before a command.
"cmp" is a command/executable, not an expression.


Last edited by boughtonp; 05-13-2021 at 10:58 AM.
 
1 members found this post helpful.
Old 05-13-2021, 11:15 AM   #4
centguy
Member
 
Registered: Feb 2008
Posts: 589

Original Poster
Blog Entries: 1

Rep: Reputation: 45
Sorry,

the script content is

Code:
if [ ! cmp -s A B ]; 
then
  echo A and B are different
fi
but the error is

Quote:

./scr: line 1: [: too many arguments

Last edited by centguy; 05-15-2021 at 10:13 AM.
 
Old 05-13-2021, 12:42 PM   #5
EdGr
Member
 
Registered: Dec 2010
Location: California, USA
Distribution: I run my own OS
Posts: 920

Rep: Reputation: 442Reputation: 442Reputation: 442Reputation: 442Reputation: 442
The square bracket interprets its argument as an expression. The script should not put square brackets around a command.

Do "man bash" and search for "test expr".
Ed
 
1 members found this post helpful.
Old 05-13-2021, 03:21 PM   #6
teckk
Senior Member
 
Registered: Oct 2004
Distribution: Arch
Posts: 4,596
Blog Entries: 5

Rep: Reputation: 1624Reputation: 1624Reputation: 1624Reputation: 1624Reputation: 1624Reputation: 1624Reputation: 1624Reputation: 1624Reputation: 1624Reputation: 1624Reputation: 1624
Couple of examples. If this is what you are looking for.
Code:
echo "Mary had a little lamb" > A
echo "Mary had a little" > B

cmp A B
A B differ: byte 18, line 1

#######

if cmp A B | grep "differ"; then
    echo "They are different"
else
    echo "They are the same"
fi
A B differ: byte 18, line 1
They are different

if cmp A A | grep "differ"; then
    echo "They are different"
else
    echo "They are the same"
fi
They are the same

########

if [[ "$(cmp A B)" =~ "differ" ]]; then
    echo "They are different"
else
    echo "They are the same"
fi
They are different

if [[ "$(cmp A A)" =~ "differ" ]]; then
    echo "They are different"
else
    echo "They are the same"
fi
They are the same

#######

[[ "$(cmp A B)" == *"differ"* ]] && echo "Yes" || echo "No"
Yes
[[ "$(cmp A A)" == *"differ"* ]] && echo "Yes" || echo "No"
No
 
1 members found this post helpful.
Old 05-13-2021, 11:42 PM   #7
centguy
Member
 
Registered: Feb 2008
Posts: 589

Original Poster
Blog Entries: 1

Rep: Reputation: 45
Thank you folks!

I thought cmp returns True or False but it gives a chunck of text if there is a difference.
 
Old 05-14-2021, 01:41 AM   #8
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 19,902

Rep: Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740
The general approach is:
if <commandA>; then <commandB> else <commandC> fi
<commandA> can be anything, if will only examine its exit code. So test, [, cmp or anything which can return an exit code should work.
! will just reverse the condition, exchange the than/else parts.

Quote:
Originally Posted by centguy View Post
I think in bash,
this works.
Code:
if ! cmp -s A B;
then
echo A and B are different
fi
This one should work if A and B are two files. Would be nice to know what was your problem with it.

Quote:
Originally Posted by centguy View Post
Strangely enough
this won't work

Code:
if [ ! cmp -s A B ]; then
then
echo A and B are different
fi
it says too many arguments.
This is just wrong. The command [ (or test) has a well defined syntax and in general it accepts 2 or 3 arguments (excluding !). 4 arguments is just useless. The test command does not operate on exit codes, but expressions, therefore you can use the text produced by commands - that is the $(command) syntax.

Regarding
Code:
cmp A B | grep text
This will work the same way, the line will return an exit code (in this case produced by grep) and actually we don't really care about the exit code of cmp (which would be good enough). Additionally (in general) we must not rely on the text printed by cmp, that may cause strange things, but the exit code of cmp.

Quote:
Originally Posted by centguy View Post
I thought cmp returns True or False but it gives a chunck of text if there is a difference.
That is [almost] true. cmp returns with an exit code, 0 means ok (or true) - files are the same, anything else means not ok (False) - files are different. if can handle it perfectly. You do not need to analyze the report of cmp to know the answer. see man page of cmp.
 
1 members found this post helpful.
Old 05-14-2021, 01:43 AM   #9
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,578

Rep: Reputation: Disabled
cmp -s doesn't print anything, it only returns an exit code:
Quote:
An exit status of 0 means no differences were found, 1 means some differences were found, and 2 means trouble.
 
1 members found this post helpful.
Old 05-15-2021, 03:40 AM   #10
centguy
Member
 
Registered: Feb 2008
Posts: 589

Original Poster
Blog Entries: 1

Rep: Reputation: 45
The problem is essentially solved.


A bit of a long story. I looked up internet and found this works

Code:
if cmp -s A B; then
  echo same
else
  echo diff
fi
Then I decided that I want to skip echo same but

Code:
if cmp -s A B; then
  #echo same
else
  echo diff
fi
simply won't work.

It says
Code:
./simple: line 3: syntax error near unexpected token `else'
./simple: line 3: `else
which is rather stupid.

If Fortran, this works:

Code:
if (a == b) then
else
  write(*,*) 'a is not equal to b'
endif
In C, this works too
Code:
  if( strcmp("a","b") == 0 ) {
  } else
  {
    printf("a is not equal to b\n");
  }

The trouble starts when I tried to take "the negative" of

if cmp -s A B; then


A general question. Is everybody forced to take a negative just to avoid an empty statement?

Last edited by centguy; 05-15-2021 at 03:44 AM.
 
Old 05-15-2021, 03:48 AM   #11
centguy
Member
 
Registered: Feb 2008
Posts: 589

Original Poster
Blog Entries: 1

Rep: Reputation: 45
i think I have to learn the proper use of $?

as in

 
Old 05-15-2021, 04:14 AM   #12
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,578

Rep: Reputation: Disabled
Quote:
Originally Posted by centguy View Post
A general question. Is everybody forced to take a negative just to avoid an empty statement?
Nope.
Code:
cmp -s A B || echo diff
Or, if you prefer using the if statement:
Code:
if cmp -s A B
then :
else echo diff
fi
Although taking a negative condition is easier (and IMO, more readable) in this case:
Code:
if ! cmp -s A B
then echo diff
fi
BTW, some shells (zsh, yash, busybox hush) would allow an empty then branch.

Last edited by shruggy; 05-15-2021 at 04:35 AM.
 
Old 05-15-2021, 04:47 AM   #13
michaelk
Moderator
 
Registered: Aug 2002
Posts: 24,145

Rep: Reputation: 5347Reputation: 5347Reputation: 5347Reputation: 5347Reputation: 5347Reputation: 5347Reputation: 5347Reputation: 5347Reputation: 5347Reputation: 5347Reputation: 5347
Code:
 if( strcmp("a","b") == 0 ) {
  } else
  {
    printf("a is not equal to b\n");
  }
With respect to c or FORTRAN bash does have some unusual syntax rules. However, being forced or silly to use a negative condition when both c and FORTAN have A!=B constructs to then use if-then-else seems just sloppy coding. However, what ever you are used to and what is more readable to you is probably more important.

shruggy has already posted the examples to make bash look similar to the code you are used to using.
 
1 members found this post helpful.
Old 05-15-2021, 10:32 AM   #14
centguy
Member
 
Registered: Feb 2008
Posts: 589

Original Poster
Blog Entries: 1

Rep: Reputation: 45
Appreciate shruggy and michaelk and teckk comments:

I summarize the discussion so that those who wants to play with it can simply cut and paste:

Script:

Code:
echo "Mary had a little lamb" > A
echo "Mary had not a little lamb" > B

echo "Test 1"
if cmp -s A A
then :
else 
  echo diff
fi

echo "Test 2"
if cmp -s A B
then :
else 
  echo diff
fi

echo "Test 3"
cmp -s A A && echo same || echo diff

echo "Test 4"
cmp -s A B && echo same || echo diff
Result:

Code:
Test 1
Test 2
diff
Test 3
same
Test 4
diff
 
Old 05-15-2021, 01:14 PM   #15
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 19,902

Rep: Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740Reputation: 6740
Quote:
Originally Posted by centguy View Post
The problem is essentially solved.

Then I decided that I want to skip echo same but

Code:
if cmp -s A B; then
  #echo same
else
  echo diff
fi
simply won't work.

It says
Code:
./simple: line 3: syntax error near unexpected token `else'
./simple: line 3: `else
which is rather stupid.

A general question. Is everybody forced to take a negative just to avoid an empty statement?
No, it is not that stupid. You have to put something between the two keywords then and else.
It is still valid for your c example too (where you omit the then, but cannot omit the {}).
 
  


Reply


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
cmp or diff? which is more accurate? work for any file? fuzzylogic25 Linux - Newbie 1 06-09-2010 01:00 AM
/bin/sh: cmp: command not found - when compile 2.6.15 again . -=Graz=- Slackware 7 05-05-2006 08:39 PM
LXer: CMP Media's Annual Embedded Systems Conference Returns to Silicon Valley, April 3-7, 2006 at San Jose's McEnery Convention Center LXer Syndicated Linux News 0 12-22-2005 02:46 PM
Help me where to find 'cmp' sohard2reg Amigo 1 03-19-2005 02:54 AM
which should I use? diff cmp comm Frybyte Linux - Newbie 2 07-19-2004 08:22 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 04:19 PM.

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