LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
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 04-30-2014, 06:18 AM   #1
stf92
Senior Member
 
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 4,442

Rep: Reputation: 76
if [ ! -a foo ] does not do what it's expected to do?


Hi:
Code:
$ cat t1.sh
#!/bin/sh

set -e
set -x
if [ ! -a /mnt/cd0 ] ; then
	mkdir /mnt/cd0
fi
$ ./t1.sh
+ '[' '!' -a /mnt/cd0 ']'
+ mkdir /mnt/cd0
mkdir: cannot create directory '/mnt/cd0': File exists
If I use -d instead of -a then it doesn't execute 'mkdir /mnt/cd0', as expected. But the bash man page says:
Code:
      -a file
              True if file exists.
/mnt/cd0 is a directory. But then it is a file! And then t1.sh should not have executed 'mkdir /mnt/cd0'. But it does. What am I missing here?
How do you explain this?
 
Old 04-30-2014, 07:03 AM   #2
Ser Olmy
Senior Member
 
Registered: Jan 2012
Distribution: Slackware
Posts: 3,340

Rep: Reputation: Disabled
It seems bash has some very peculiar ideas about the nature of directories. The output from this script only makes sense in a particular universe:
Code:
#!/bin/bash

mkdir /tmp/tea

if [ -a /tmp/tea ]; then
  echo You have tea.
fi

if [ ! -a /tmp/tea ]; then
  echo You have no tea.
fi

rmdir /tmp/tea
As you said, the results are specific to the -a operator; the -d operator produces the expected result(s), and so does the -a operator if you put it inside double brackets ([[ / ]]).

This has to be a bug.
 
Old 04-30-2014, 07:12 AM   #3
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
you may just as well use mkdir -p

no point in you checking then the kernel checking again.
 
1 members found this post helpful.
Old 04-30-2014, 07:38 AM   #4
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
I agree with the suggestion to use:
Code:
mkdir -p <dir-path-and-name>
However I also feel that for things like temporary mount points that it's best to create that as well as remove it so as to not leave temporary unused files lying around. Further, there is a test concern to consider which is if that directory does exist, then is it already a mount for some other reason, so as a result the script should consider making that determination, failing, or trying to use an alternate mount point so as to not cause undesired system problems.
 
Old 04-30-2014, 09:30 AM   #5
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
I think is a quirk due to -a having 2 meanings for the test (aka "[") builtin:
Code:
$ help test
...
      -a FILE        True if file exists.
      EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
      STRING         True if string is not empty.
      -e FILE        True if file exists.
[ ! -a /tmp/tea ] is true because "!" is "true" (it's a nonempty string), and "/tmp/tea" is "true" for the same reason. Note that -e means the same as unary -a, and doesn't have this problem. Also you can put the "!" outside of the test:
Code:
! [ -a /tmp/tea ]
 
4 members found this post helpful.
Old 04-30-2014, 07:00 PM   #6
stf92
Senior Member
 
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 4,442

Original Poster
Rep: Reputation: 76
Not remembering what the logical negation operator was, I looked in the internet and saw it was used this way:
Code:
if [ ! -<some primary> <filename> ]
But
Code:
if ! [ -<unary primary> <filename> ]
should be preferred I think, because it makes it clear what the scope of '!' is. In the case of '-a' if forces bash to interpret it as a unary operator. Thanks for the feedback.
 
Old 04-30-2014, 07:11 PM   #7
Ser Olmy
Senior Member
 
Registered: Jan 2012
Distribution: Slackware
Posts: 3,340

Rep: Reputation: Disabled
Quote:
Originally Posted by ntubski View Post
I think is a quirk due to -a having 2 meanings for the test (aka "[") builtin:
Of. Course. Putting the ! operator before the -a basically turned the test into:
Code:
if [ foo -a bar ]
 
  


Reply



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
Difference between ./foo, . foo and source foo? stf92 Linux - Newbie 7 04-26-2014 01:04 AM
[SOLVED] C: isn't foo[30] a pointer? Assume declaration char foo[30]. stf92 Programming 11 01-25-2014 10:31 AM
[SOLVED] Apache: RewriteRule - redirect /foo only works if /foo exists ezekieldas Linux - Software 2 07-31-2012 11:45 AM
Killing foo, which I started as foo &. stf92 Linux - Newbie 9 11-08-2010 10:54 PM
Which config file should I use... foo or foo.new? davidguygc Slackware 6 08-01-2007 05:21 PM

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

All times are GMT -5. The time now is 02:10 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