Fedora Linux Support Community & Resources Center
  #1  
Old 11th November 2011, 09:02 AM
glennzo Offline
Un-Retired Administrator
 
Join Date: Mar 2004
Location: Salem, Mass USA
Posts: 14,543
linuxchrome
Bash code sample - Is this correct?

Bash script testing to see if 2 files exist.
The following is correct? Seems to work as expected.
PHP Code:
ifile=/some/file/somewhere
sfile
=/another/file/somewere

if [[ ! -${ifle,sfile} ]] ; then 
And this is not? This always tells me that $ifile is missing and never seems to get to $sfile.
PHP Code:
if [[ ! -{$ifile,$sfile} ]] ; then 
Bash documentation is plentiful. Trying to understand the documentation sometimes makes my head hurt. Anyhow, can anyone confirm that method 1 is in fact the correct method?
__________________
Glenn
The Bassinator © ®

[SIGPIC][/SIGPIC]
Laptop: Toshiba Satellite / Intel Core 2 Duo 1.73 GHz / 2GB / 160GB / Intel Mobile 945GM/GMS/GME/943/940GML Integrated Graphics
Desktop: BioStar MCP6PB M2+ / AMD Phenom 9750 Quad Core / 4GB / 1TB SATA / 500GB SATA / EVGA GeForce 8400 GS 1GB
Reply With Quote
  #2  
Old 11th November 2011, 09:30 AM
stevea Offline
Registered User
 
Join Date: Apr 2006
Location: Ohio, USA
Posts: 8,553
linuxfedorafirefox
Re: Bash code sample

Maybe this helps explain the behavior ....

Code:
[stevea@lycoperdon etc]$ ifile=/some/file/somewhere
[stevea@lycoperdon etc]$ sfile=/another/file/somewere 

[stevea@lycoperdon etc]$ echo ${ifle,sfile}   # note typo

[stevea@lycoperdon etc]$ echo ${ifile,sfile}
/some/file/somewhere
[stevea@lycoperdon etc]$ echo {$ifile,$sfile}
/some/file/somewhere /another/file/somewere
[stevea@lycoperdon etc]$ echo abc{123,456}
abc123 abc456
[stevea@lycoperdon etc]$ STR1="ABCDEF"
[stevea@lycoperdon etc]$ echo ${STR1,"C"}
ABcDEF

So the feature where we have the shell some strings like "abc{123,456}" and it results in "abc123 abc456" is called "Brace Expansion".

But the expansion of ${foo,bar} is Parameter Expansion method which converts uppercase letters to lowercase.

Neither does what you intend since the '-f' test can only test one file at a time. You need an expression like ..
[[ ! -f $file1 -o ! -f $file2 ]] # this condition is true unless BOTH files exist

[[ ! -f $file1 -o ! -f $file2 ]] && echo "Files are missing" >&2 && exit 2
__________________
None are more hopelessly enslaved than those who falsely believe they are free.
Johann Wolfgang von Goethe

Last edited by stevea; 11th November 2011 at 09:50 AM.
Reply With Quote
  #3  
Old 11th November 2011, 09:31 AM
Gödel Offline
Registered User
 
Join Date: Jul 2009
Location: London,England
Posts: 1,099
linuxfirefox
Re: Bash code sample - Is this correct?

I haven't used either of these forms, so can't say if they should work or not, I would do it something like this

Code:
if [[ -f "$ifile1" && -f "$sfile" ]]; then echo "ok"; fi
Reply With Quote
  #4  
Old 11th November 2011, 10:05 AM
stevea Offline
Registered User
 
Join Date: Apr 2006
Location: Ohio, USA
Posts: 8,553
linuxfedorafirefox
Re: Bash code sample - Is this correct?

I suppose we can handle a variable number of files like this ....
filelist="/etc/fstab /etc/shadow /etc/passwd /etc/group"
if for f in $filelist; do [[ ! -f $f ]] && break ; done ; then echo MISSING; else echo ALL PRESENT; fi


---------- Post added at 06:05 AM ---------- Previous post was at 06:00 AM ----------

Quote:
Originally Posted by Gödel View Post
I haven't used either of these forms, so can't say if they should work or not, I would do it something like this

Code:
if [[ -f "$ifile1" && -f "$sfile" ]]; then echo "ok"; fi
It's a semantic issue but ...that condition is only true if both files don't exist.
NOT ifile AND NOT sfile
Neither.

I *suspect* that's not what Glen wants to test.
__________________
None are more hopelessly enslaved than those who falsely believe they are free.
Johann Wolfgang von Goethe
Reply With Quote
  #5  
Old 11th November 2011, 10:06 AM
glennzo Offline
Un-Retired Administrator
 
Join Date: Mar 2004
Location: Salem, Mass USA
Posts: 14,543
linuxchrome
Re: Bash code sample - Is this correct?

Thanks for the replies guys.

Steve, your explanation is wonderful. It also reminded me that I can do some testing right at the command line. Thank you for that.

Godel. I inserted your code into my script and it seems to work. Thank you.


PHP Code:
#!/bin/bash
ifile="/usr/sbin/includes"
cfile="/usr/sbin/scolors"
#
if [[ -"$ifile&& -"$cfile]] ; then
   
echo "Files found."
else
   echo 
"Files not found." 2>&1
   
exit 1
fi
exit 
__________________
Glenn
The Bassinator © ®

[SIGPIC][/SIGPIC]
Laptop: Toshiba Satellite / Intel Core 2 Duo 1.73 GHz / 2GB / 160GB / Intel Mobile 945GM/GMS/GME/943/940GML Integrated Graphics
Desktop: BioStar MCP6PB M2+ / AMD Phenom 9750 Quad Core / 4GB / 1TB SATA / 500GB SATA / EVGA GeForce 8400 GS 1GB
Reply With Quote
  #6  
Old 11th November 2011, 10:07 AM
glennzo Offline
Un-Retired Administrator
 
Join Date: Mar 2004
Location: Salem, Mass USA
Posts: 14,543
linuxchrome
Re: Bash code sample - Is this correct?

Glenn wants to make sure BOTH files exist. If not , exit the script.


Using Godels code and running the script.

Code:
[glenn@fedora16 ~>$ ./fed_hosts.sh 
Files found.
For what it's worth the files actually do exist on this machine.

This script, when finished, will simply add some local ip addresses and host names to /etc/hosts. I'll be using it here at home on physical and virtual installs of Fedora.

Let me explain further. I'm trying to learn bash scripting. I've stuck with this for a couple months now but I need something to actually script. I've installed Fedora 15 under VirtualBox to use as a test system. I thought I'd try to script some of the things I always do to a new Fedora install like add host name and ip addresses to /etc/hosts, add aliases to my and root's bashrc, add yum repositories including rpmfusion, install many of the packages that I usually install, etc. So, my fed_hosts script adds those host names and ip addresses but I wanted to make sure that /etc/hosts actually exists and that my "include" files actually exist before allowing the script to complete. My 'includes" handle colored text and have a few functions like making sure user is root when executing scripts, making sure we're running the correct release of Fedora in some cases, etc.

Having said that, the program flow would be something on the order of:

Make sure include files exist (for functions and colored text)
Make sure user is root (because of permission issues)
Make sure release version is correct if I necessary
Make sure target files exist
Make changes to target files (I should probably backup the target files first)
Exit script.

Most of my scripts seem to work as expected so now I'm making changes to shorten the scripts and trying to learn to do things in a more sensible and proper way. I used brace expansion in a short script the other day and it worked well, allowing me to turn six lines of code into 2 or 3 lines of code, getting rid of repetition so I thought I'd try to incorporate it into some of my scripts. Seemed to make sense.

This bash scripting thing is noting more than a hobby of sorts. Something I've taken an interest in and something to do to keep me amused and out of mischief.
__________________
Glenn
The Bassinator © ®

[SIGPIC][/SIGPIC]
Laptop: Toshiba Satellite / Intel Core 2 Duo 1.73 GHz / 2GB / 160GB / Intel Mobile 945GM/GMS/GME/943/940GML Integrated Graphics
Desktop: BioStar MCP6PB M2+ / AMD Phenom 9750 Quad Core / 4GB / 1TB SATA / 500GB SATA / EVGA GeForce 8400 GS 1GB
Reply With Quote
  #7  
Old 11th November 2011, 02:50 PM
Gödel Offline
Registered User
 
Join Date: Jul 2009
Location: London,England
Posts: 1,099
linuxfirefox
Re: Bash code sample - Is this correct?

steva's right about the original logical interpretation but I assumed you just wanted to test for existence of both files, rather than use a negation operator "!", which can be taken care of by an "else" branch as you figured.

A couple of points:
Single bracket "[" tests with "-a" for the "AND" operator are not recommended (see first link below)
I forgot that variables don't need to be quoted inside double brackets "[[" when testing, unless using "=" (see second link below)

http://mywiki.wooledge.org/BashPitfa...22_.3D_foo_.5D
http://mywiki.wooledge.org/BashPitfa...g_on_intent.29
Reply With Quote
  #8  
Old 12th November 2011, 10:19 AM
glennzo Offline
Un-Retired Administrator
 
Join Date: Mar 2004
Location: Salem, Mass USA
Posts: 14,543
linuxfirefox
Re: Bash code sample - Is this correct?

Thanks for the links Godel. Interesting reading and something I think I'll bookmark.

I wonder if maybe I should just forget about expansion of any sort in this particular instance.

Edit: New logic for this "issue". Both files need to exist. If one or the other is missing then they need to be installed and will be installed at the same time. I really only need to test for one or the other, not necessary to test for both.
__________________
Glenn
The Bassinator © ®

[SIGPIC][/SIGPIC]
Laptop: Toshiba Satellite / Intel Core 2 Duo 1.73 GHz / 2GB / 160GB / Intel Mobile 945GM/GMS/GME/943/940GML Integrated Graphics
Desktop: BioStar MCP6PB M2+ / AMD Phenom 9750 Quad Core / 4GB / 1TB SATA / 500GB SATA / EVGA GeForce 8400 GS 1GB
Reply With Quote
  #9  
Old 12th November 2011, 01:57 PM
Gödel Offline
Registered User
 
Join Date: Jul 2009
Location: London,England
Posts: 1,099
linuxfirefox
Re: Bash code sample - Is this correct?

I forgot to post a link to this section too:

What is the difference between test, [ and [[ ?
Reply With Quote
  #10  
Old 13th November 2011, 03:28 PM
stevea Offline
Registered User
 
Join Date: Apr 2006
Location: Ohio, USA
Posts: 8,553
linuxfedorafirefox
Re: Bash code sample - Is this correct?

Quote:
Originally Posted by Gödel View Post
I forgot to post a link to this section too:

What is the difference between test, [ and [[ ?
Thanks Gödel. But that link contains severe errors.

They use the term "pattern matching" where they mean "string comparison" - two different concepts.
Much more troubling that FAIL to correctly describe the distinction between string and integer comparison operators.

In "old Bash"" single '[' as they call it, they claim that \> and -gt can be used interchangeable for integer comparison but that is provably false. \> is always and only a STRING comparison and -lt is always and only an integer comparison, Here is an example of the error

Code:
[stevea@crucibulum Desktop]$ [ 5 \< 6 ] && echo YES || echo NO
YES
[stevea@crucibulum Desktop]$ [ 5 -lt 6 ] && echo YES || echo NO
YES
[stevea@crucibulum Desktop]$ [ 5 -lt 06 ] && echo YES || echo NO
YES
[stevea@crucibulum Desktop]$ [ 5 \< 06 ] && echo YES || echo NO
NO
So clearly the \< type operators always promote their arguments to string types and then compare these lexically. 5 is lexically less than 6 but not lexically less than 06.

Any scripts written with the wrong type of operator may fail to operate as intended given perfectly valid input.

So as the bash man page states clearly under "CONDITIONAL EXPRESSIONS"
"-eq, -ne, -lt, -le, -gt, or -ge" are arithmetic binary operators, and
"= == != < >" are string binary operators.
THEY ARE NOT INTERCHANGEABLE.

==========================================

The bottom line is that '[[' is less portable. It is NOT defined by POSIX which only allows it as an implementation specific keyword. My personal concerns always go to porting scripts to embedded systems with old v3 bash or even busybox 'sh'.

I'm not suggesting anyone NOT use '[[', but one must consider if there is compelling value.
That '[[' makes the quoting unnecessary is a small value, but it also makes the already complex bash quoting scheme even more complex. When we see
Quote:
var="foo bar"
cmd $var
then we naturally expect that cmd has two arguments (argc=3), but with the peculiar '[[' scheme violates that expectation.

I'll scan the source but the advantages look slim to me.
__________________
None are more hopelessly enslaved than those who falsely believe they are free.
Johann Wolfgang von Goethe
Reply With Quote
  #11  
Old 14th November 2011, 12:10 AM
Gödel Offline
Registered User
 
Join Date: Jul 2009
Location: London,England
Posts: 1,099
linuxfirefox
Re: Bash code sample - Is this correct?

yes, you're right about the -lt and \< issue (which is also true in '[[' tests), but otherwise the info looks ok, eg it points out the important bit about locale collating for string comparisons in '[[' being guaranteed since bash 4.1. btw the bash documentation uses the term 'pattern matching' , type 'help [['

Code:
$ help [[
...
When the `==' and `!=' operators are used, the string to the right of
    the operator is used as a pattern and pattern matching is performed.
    When the `=~' operator is used, the string to the right of the operator
    is matched as a regular expression.
...
Reply With Quote
Reply

Tags
bash, code, correct, sample

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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 On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
just formated to SATA drives with FAT16 FS, fdisk -l displays: [code] bash-3.2$ sud manuleka Hardware & Laptops 4 21st May 2009 09:01 PM
Walk through or sample weave Installation, Upgrades and Live Media 3 7th January 2007 10:48 PM
fstab sample nocturnus_gr Using Fedora 1 15th July 2005 02:40 PM
No correct keypad code on FC3 console woosting EOL (End Of Life) Versions 3 22nd February 2005 10:02 AM
Bash Profile Sample 07dcolem Using Fedora 6 29th November 2004 02:10 AM


Current GMT-time: 06:59 (Wednesday, 23-04-2014)

TopSubscribe to XML RSS for all Threads in all ForumsFedoraForumDotOrg Archive
logo

All trademarks, and forum posts in this site are property of their respective owner(s).
FedoraForum.org is privately owned and is not directly sponsored by the Fedora Project or Red Hat, Inc.

Privacy Policy | Term of Use | Posting Guidelines | Archive | Contact Us | Founding Members

Powered by vBulletin® Copyright ©2000 - 2012, vBulletin Solutions, Inc.

FedoraForum is Powered by RedHat