LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
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 05-24-2012, 06:52 AM   #1
newbiecolonopenparens
LQ Newbie
 
Registered: May 2012
Posts: 8

Rep: Reputation: Disabled
Problem with analyzing command line arguments: bash shell script


So far, my code looks like this:
Code:
commands=$@
for arg in commands
do
    # echo $arg
    if [ $arg == "-print" ] then
        # do something
    if [ $arg == "-name" ] then
        # do something
    ...
done
The problem I have is that for some reason, the if statements get skipped when I type in a prompt like: ./program -name newb -print
I double checked to make sure that the correct arg was being passed in as well. Any suggestions?
 
Old 05-24-2012, 06:57 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 23,715

Rep: Reputation: 7827Reputation: 7827Reputation: 7827Reputation: 7827Reputation: 7827Reputation: 7827Reputation: 7827Reputation: 7827Reputation: 7827Reputation: 7827Reputation: 7827
you can add the following line before this loop:
set -xv
to see what's happening
 
Old 05-24-2012, 06:59 AM   #3
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,148
Blog Entries: 2

Rep: Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886
You forgot the fi to end the if statements:
Code:
commands=$@
for arg in commands
do
    # echo $arg
    if [ $arg == "-print" ] then
        # do something
    fi
    if [ $arg == "-name" ] then
        # do something
    fi
    ...
done
However, for test like this you should have a look at the "case" statement.
 
Old 05-24-2012, 11:19 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Arch
Posts: 10,031

Rep: Reputation: 3202Reputation: 3202Reputation: 3202Reputation: 3202Reputation: 3202Reputation: 3202Reputation: 3202Reputation: 3202Reputation: 3202Reputation: 3202Reputation: 3202
I would query the purpose of assigning $@ to a variable and not just using it as is?

Also, if used directly you either need to quote it or remove it all together, like:
Code:
for arg
do
    ...
 
Old 05-24-2012, 03:25 PM   #5
newbiecolonopenparens
LQ Newbie
 
Registered: May 2012
Posts: 8

Original Poster
Rep: Reputation: Disabled
Well, I did include the fi's to close the if statements. This was posted before I slept, so sorry if I left those out. I did commands=$@ instead of directly doing for arg in $@ because I thought I was losing words when I used shift 1 inside the if statements
 
Old 05-24-2012, 06:56 PM   #6
newbiecolonopenparens
LQ Newbie
 
Registered: May 2012
Posts: 8

Original Poster
Rep: Reputation: Disabled
So, is it wrong of me to shift through my arguments, even though i keep track of it myself?
I was doing:
find
Code:
for arg in $@
do
    if [ $arg == "name" ]
    then
        shift 1
        echo "$1"
    fi
    if [ $arg == "type" ]
    then
        shift 1
        if [ -f $1 ] then
        #echo all directories out. Is this where it's wrong? how do i check the next argument in the loop?
        #maybe something like string=($arg+1)
        #so that i can do if [ -f $string ] ?
        fi
    fi
done
 
Old 05-24-2012, 09:03 PM   #7
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,426

Rep: Reputation: 2786Reputation: 2786Reputation: 2786Reputation: 2786Reputation: 2786Reputation: 2786Reputation: 2786Reputation: 2786Reputation: 2786Reputation: 2786Reputation: 2786
1. 'shift 1'; '1' is redundant ie just 'shift' is enough/default
2. Try using getopts instead of rolling your own code http://wiki.bash-hackers.org/howto/getopts_tutorial

http://rute.2038bug.com/index.html.gz
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/
 
Old 05-24-2012, 09:29 PM   #8
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
You need to first take the time to understand exactly how the shell uses arguments, and the "@" form of parameter expansion in particular.

To start with, read these three links:

http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes


Now, $@ outputs all the parameter arguments as separate entities, but only if you quote it first. Otherwise the shell simply word-splits it back out again. So always double quote it. The "${array[@]}" array expansions work the same way.

Your first attempt:
Code:
commands=$@
for arg in $commands ; do
This is bad. First it puts the entire contents of $@ into a single scalar variable, then it relies on word-splitting that variable back into pieces for the for loop to iterate over.


Now if you really want to back-up/duplicate the $@ parameters, set them into an array.

Code:
commands=( "$@" )
for arg in "${commands[@]}"; do
Now the strings are never left unprotected.

Do note however that while the $@ parameters start with "1", array indexes start with "0", so you'll have to do a bit of math if you need them to match up. Or else start with a dummy 0 array entry before you populate it.

Code:
commands[0]=""		#start with an empty array 0
commands+=( "$@" )	#+= appends entries to an existing array
unset commands[0]	#unset 0, so command 1 will be the first one in the array

for arg in "${commands[@]}"; do
This way "$1" and "${commands[1]}", etc. should be identical.


How can I use array variables?
http://mywiki.wooledge.org/BashFAQ/005



Now for a few more points:


When using bash or ksh, it's recommended to use ((..)) for numerical tests, and [[..]] for string/file tests and complex expressions. Avoid using the old [..] test unless you specifically need POSIX-style portability.

http://mywiki.wooledge.org/ArithmeticExpression
http://mywiki.wooledge.org/BashFAQ/031
http://wiki.bash-hackers.org/commands/classictest
http://wiki.bash-hackers.org/syntax/...nal_expression


When testing the contents of a single variable for multiple values, you should use a single case statement, instead of multiple if..elif..thens.

http://wiki.bash-hackers.org/syntax/ccmd/case


Finally, since you appear to be trying to create an option parser of some kind, I recommend you take a look at the built-in getopts instead. No need to reinvent the wheel if you don't have to.

http://wiki.bash-hackers.org/howto/getopts_tutorial
 
  


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
How to pass command line arguments from one shell script to another shell script VijayaRaghavanLakshman Linux - Newbie 5 01-20-2012 10:12 PM
[SOLVED] ? running shell script taking command line arguments in a jsp page? etika Linux - Newbie 1 02-11-2011 02:26 AM
[SOLVED] bash command line arguments izghitu Linux - Software 4 07-01-2010 10:23 AM
getting command line arguments in bash DEF. Programming 4 05-06-2009 12:50 PM
Bash command line arguments msreddy999 Programming 1 03-20-2009 03:56 PM

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

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