LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 03-22-2013, 07:21 AM   #1
qingyangzhang2@163.com
LQ Newbie
 
Registered: Mar 2013
Posts: 2

Rep: Reputation: Disabled
Smile linux bash


hello every one!
i hava a question. i'm a newer for linux bash. i make a code segment like the follows.

#!/bin/bash
aa="/usr/local/tmp/test.txt"
dd="/usr/local/tmp/dd"


and i can make sure two of them was existens. aa is a file,dd is a directory .but the following code is not do well.
if[ -a "${aa}" ] ; then
echo "${aa} is a file"
elif [ -d "${dd}" ] ; then
ehco "${dd} is a directory "

fi;


the elif condition is always not running. anybody tell me why? thks

Last edited by qingyangzhang2@163.com; 03-22-2013 at 07:25 AM. Reason: sorry ,i make a mistake .
 
Old 03-22-2013, 07:37 AM   #2
sycamorex
LQ Veteran
 
Registered: Nov 2005
Location: London
Distribution: Slackware64-current
Posts: 5,836
Blog Entries: 1

Rep: Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251
Hi and welcome to LQ.

A couple of comments:

- it's probably not a good practice to call your variable ("dd") exactly like a potentially dangerous tool (dd)
- You've got a lot of typos in the code above. I assume they are correct in your script. Please use the code tags when submitting any code in your posts.
- If the first condition is met (ie. the file exists), it is correct that it will never reach the second one (elif).

Have a look at this tutorial to understand the logic behind it:
http://tldp.org/LDP/Bash-Beginners-G...ect_07_02.html
 
3 members found this post helpful.
Old 03-22-2013, 03:50 PM   #3
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Quote:
Originally Posted by qingyangzhang2@163.com View Post
hello every one!
i hava a question. i'm a newer for linux bash. i make a code segment like the follows.

#!/bin/bash
aa="/usr/local/tmp/test.txt"
dd="/usr/local/tmp/dd"


and i can make sure two of them was existens. aa is a file,dd is a directory .but the following code is not do well.
if[ -a "${aa}" ] ; then
echo "${aa} is a file"
elif [ -d "${dd}" ] ; then
ehco "${dd} is a directory "

fi;


the elif condition is always not running. anybody tell me why? thks
The -a (which is the same as the -e) tests to see if a file exists... and a directory is a file. If you wanted to see if a file was a regular file then use the -f test (True if file exists AND is a regular file).
 
1 members found this post helpful.
Old 03-22-2013, 04:05 PM   #4
guyonearth
Member
 
Registered: Jun 2012
Location: USA
Distribution: Ubuntu
Posts: 424

Rep: Reputation: 83
Bash is not like HTML or CSS which ignores both extra spaces and lack of spaces. Your code is not properly formatted. Also, as the other person mentioned, dd is not a good choice for a variable, since it's an existing command/program and should be reserved for that.
 
1 members found this post helpful.
Old 03-23-2013, 02:17 AM   #5
Ztcoracat
LQ Guru
 
Registered: Dec 2011
Distribution: Slackware, MX 18
Posts: 9,484
Blog Entries: 15

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Quote:
Originally Posted by guyonearth View Post
Bash is not like HTML or CSS which ignores both extra spaces and lack of spaces. Your code is not properly formatted. Also, as the other person mentioned, dd is not a good choice for a variable, since it's an existing command/program and should be reserved for that.
Doesn't (dd) imply destroy disk?
 
Old 03-23-2013, 03:52 AM   #6
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Quote:
Originally Posted by qingyangzhang2@163.com View Post
...the elif condition is always not running. anybody tell me why? thks
The reason is pretty simple. If the if condition executes as true then else condition will not be executed. In your case, the if condition i.e. if[ -a "${aa}" ] is executing as true, thus else or elif condition isn't executing.

If you want to execute both conditions, do it like this:
Code:
#!/bin/bash
aa="/usr/local/tmp/test.txt"
bb="/usr/local/tmp/dd"
if [[ -a "${aa}" ]] ; then
echo "${aa} is a file"
if [[ -d "${bb}" ]] ; then
echo "${bb} is a directory "
fi
fi
Note: As per above discussions, use bb for storing directory name instead of dd.
 
Old 03-23-2013, 04:44 AM   #7
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Quote:
Originally Posted by Ztcoracat View Post
Doesn't (dd) imply destroy disk?
No.

The dd command is "data dump". It CAN destroy data on a disk when improperly used. But so can "cat".
 
Old 03-23-2013, 05:09 AM   #8
qingyangzhang2@163.com
LQ Newbie
 
Registered: Mar 2013
Posts: 2

Original Poster
Rep: Reputation: Disabled
Talking

Quote:
Originally Posted by Ztcoracat View Post
Doesn't (dd) imply destroy disk?
fortunatly , it is not work
 
Old 03-23-2013, 05:32 AM   #9
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Quote:
Originally Posted by qingyangzhang2@163.com View Post
fortunatly , it is not work
The way you've used it in your script, it won't harm in any way. But it's always recommended to NOT use any executable command name in script, which is of no use actually, else it may be mis-interpreted and may cause problems to your system. A wrong use of this command may override the existing data on a disk device. So avoid using shell executables in scrips unless they're used in a proper and useful way. For more info. on dd, check it's manual here.

You can use bb instead of dd.

Last edited by shivaa; 03-23-2013 at 05:34 AM. Reason: Typo
 
Old 03-23-2013, 07:17 AM   #10
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
A bit about scripts - it is very useful to make them easy to read as that helps understand the logic used:
WARNING: pedantic mode on...

Take the original script:
Code:
#!/bin/bash
aa="/usr/local/tmp/test.txt"
dd="/usr/local/tmp/dd"
if[ -a "${aa}" ] ; then
echo "${aa} is a file"
elif [ -d "${dd}" ] ; then
echo "${dd} is a directory "
fi;
To make it more readable indent:

Code:
#!/bin/bash
aa="/usr/local/tmp/test.txt"
dd="/usr/local/tmp/dd"
if[ -a "${aa}" ] ; then
    echo "${aa} is a file"
elif [ -d "${dd}" ] ; then
    echo "${dd} is a directory "
fi;
This makes it clear that you want to distinguish between two things - a file, and a directory. It also shows that you don't specify what to do if neither condition is true (there is no "else"), but hints that more may be added...

Use of dd is discouraged not because it is wrong - but easily confused with the dd command. One reason it can be confused is because dd takes named parameters. A typical dd command is:

Code:
dd if=input conv=ebcdic of=output
And no, I don't think anybody uses EBCDIC anymore... But it points out that if the "if" (input file specification) is missed by a typographic error, you get an assignemnt...

Now lets take the next script:
Code:
#!/bin/bash
aa="/usr/local/tmp/test.txt"
bb="/usr/local/tmp/dd"
if [[ -a "${aa}" ]] ; then
echo "${aa} is a file"
if [[ -d "${bb}" ]] ; then
echo "${bb} is a directory "
fi
fi
This is even harder to scan... So lets indent:

Code:
#!/bin/bash
aa="/usr/local/tmp/test.txt"
bb="/usr/local/tmp/dd"
if [[ -a "${aa}" ]] ; then
    echo "${aa} is a file"
    if [[ -d "${bb}" ]] ; then
        echo "${bb} is a directory "
    fi
fi
This is easier to identify that the conditions are nested. It is also obvious that the logic isn't equivalent to the first example.

The underlying testing is on filesystem based items/objects. The -a test only identifies that something exists, it doesn't tell you what kind of object it is. filesystem objects are:

1. files - things that hold data
2. links - files that hold names of files in other locations
3. directories - files that hold file names (actually a file that is a list of inode number, name pairs)
4. devices - files that tie a name to a kernel structure for device input/output.
5. sockets - files that tie a bidirectional communications stream to a name.
6. fifo - files that tie a name to a pipe, a one way communication stream.

NOTE: there is a place where -a is used for "logical and", so using -a for file tests can be a bit ambigeous:

Code:
if [ $n -le 25 -a -a file ]; then
...
This is valid - most of the testing done for conditional expressions is handled not by bash, but by the "test" utility. The test utility uses -a for "and" and -e for "file exists" testing... Bash has a number of extensions, one of which is that much of the test utility is now built into bash. But confusion can result, so it would be better to use the -e for testing for the existence of a filesystem object.

Next, if you go through the man pages for bash (or easier, test), you will find that there is no explicit test for a device file... so the only way to identify a device file is to identify a special file first (as in ! -f , where the "!" is the not operator), then test for each of the listed special files...

Also remember, just because something exists doesn't mean you can read it. So there are access control tests available too.

Last edited by jpollard; 03-23-2013 at 07:19 AM.
 
Old 03-23-2013, 09:07 AM   #11
Habitual
LQ Veteran
 
Registered: Jan 2011
Location: Abingdon, VA
Distribution: Catalina
Posts: 9,374
Blog Entries: 37

Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
No.

The dd command is "data dump". It CAN destroy data on a disk when improperly used. But so can "cat".
or "disk destroyer" by many of fans of not using ANYTHING like dd, anywhere and why risk it?
Scripts have to be the opposite of risk, IMO.... so "run away" from anything even looking like 'dd'.
Your sanity will reward you.
Code:
if [ -d /usr/local/tmp/dd > 0 ]; then echo "Directory exists..." ; else echo "Directory does NOT exist." ; fi
if [ -f /usr/local/tmp/test.txt > 0 ]; then echo "File exists..." ; else echo "File does NOT exist." ; fi
1.5 hours on my Day Off working on someone else's code, how sick am I?
That "man bash" > ":/Conditional expressions" is a winner.

Last edited by Habitual; 03-23-2013 at 09:08 AM. Reason: cleaned up -f for File from Directory in echos
 
Old 03-23-2013, 09:28 AM   #12
Ztcoracat
LQ Guru
 
Registered: Dec 2011
Distribution: Slackware, MX 18
Posts: 9,484
Blog Entries: 15

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Quote:
Originally Posted by Habitual View Post
or "disk destroyer" by many of fans of not using ANYTHING like dd, anywhere and why risk it?
Scripts have to be the opposite of risk, IMO.... so "run away" from anything even looking like 'dd'.
Your sanity will reward you.
Code:
if [ -d /usr/local/tmp/dd > 0 ]; then echo "Directory exists..." ; else echo "Directory does NOT exist." ; fi
if [ -f /usr/local/tmp/test.txt > 0 ]; then echo "File exists..." ; else echo "File does NOT exist." ; fi
1.5 hours on my Day Off working on someone else's code, how sick am I?
That "man bash" > ":/Conditional expressions" is a winner.
Must have sanity to write a good script-
Not sick at all Mate; just incredibly intelligent with a strong ambition to make right what's not complete yet.
Your not alone; I find myself fixing friends OS on my days off-
 
Old 03-23-2013, 09:52 AM   #13
Ztcoracat
LQ Guru
 
Registered: Dec 2011
Distribution: Slackware, MX 18
Posts: 9,484
Blog Entries: 15

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Quote:
Originally Posted by shivaa View Post
The reason is pretty simple. If the if condition executes as true then else condition will not be executed. In your case, the if condition i.e. if[ -a "${aa}" ] is executing as true, thus else or elif condition isn't executing.

If you want to execute both conditions, do it like this:
Code:
#!/bin/bash
aa="/usr/local/tmp/test.txt"
bb="/usr/local/tmp/dd"
if [[ -a "${aa}" ]] ; then
echo "${aa} is a file"
if [[ -d "${bb}" ]] ; then
echo "${bb} is a directory "
fi
fi
Note: As per above discussions, use bb for storing directory name instead of dd.
I understand that:
Quote:
aa="/usr/local/tmp/test.txt"
Is a file and I get that:
Quote:
bb="/usr/local/tmp/dd"
Is a directory; but what does the (-d) variable imply or is this actually a flag?
And is (fi) a way to indicate exit?

Ztcoracat :~$ Still studying BASH

Last edited by Ztcoracat; 03-23-2013 at 09:54 AM. Reason: Not clear on bash
 
Old 03-23-2013, 10:13 AM   #14
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Quote:
Originally Posted by Habitual View Post
or "disk destroyer" by many of fans of not using ANYTHING like dd, anywhere and why risk it?
Because it depends on what you are doing. Disk recovery? dd. Forensics? dd. ISOs? dd.

Large data copies? dd (with a huge buffer...)

It is even used to backup partitions...

Quote:
Scripts have to be the opposite of risk, IMO.... so "run away" from anything even looking like 'dd'.
Your sanity will reward you.
No - scripts are good for recording exactly what you want to do... without forgetting steps. AND for getting exactly the right parameters and/or syntax right to work correctly.
Quote:
Code:
if [ -d /usr/local/tmp/dd > 0 ]; then echo "Directory exists..." ; else echo "Directory does NOT exist." ; fi
if [ -f /usr/local/tmp/test.txt > 0 ]; then echo "File exists..." ; else echo "File does NOT exist." ; fi
1.5 hours on my Day Off working on someone else's code, how sick am I?
That "man bash" > ":/Conditional expressions" is a winner.
Note that just because a directory does NOT exist, does NOT mean that the file doesn't exist - it might not exist, but then, the file might not be a directory either.

Last edited by jpollard; 03-23-2013 at 10:15 AM.
 
Old 03-23-2013, 10:19 AM   #15
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Quote:
Originally Posted by Ztcoracat View Post
I understand that:

Is a file and I get that:

Is a directory; but what does the (-d) variable imply or is this actually a flag?
And is (fi) a way to indicate exit?

Ztcoracat :~$ Still studying BASH
-d is not a variable - it is a test - if the name exists, AND it is a directory.


fi is the end of the if block (hence my recommendation to indent...)

Code:
if [ ... ]; then
    ...
elsif [ ... ]; then
    ...
else
    ...
fi
 
  


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
Bash problem : -bash: [: /bin/bash: unary operator expected J.A.X Linux - Software 1 09-22-2011 05:52 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

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