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 03-08-2011, 03:46 AM   #1
greengrocer
Member
 
Registered: Aug 2005
Distribution: Ubuntu Intrepid and Meerkat, formerly used Debian 3.1 (Sarge) with Gnome Desktop
Posts: 353

Rep: Reputation: 37
Bash Scripts - need help with variables


Hello all,

I want to create a script that processes parameters which a user might specify when they call my script.

example of how I want my script to be able to be used:

Code:
sh myscript red green orange
I'd imagine I want to be able to do something like:

Code:
p=1
 for ARG in "$@"
  do
  I want to make a variable(p) contain whatever the first parameter is
  let p=p+1
  and then variable(p) contain whatever the second parameter is
  and so on until there are no more parameters.  
done
In usage, the user calling my script could specify any quantity of parameters.

I am just not sure how to go about getting variables like this to work. Can anybody point me in the correct direction?

Cheers,
Greenie
 
Old 03-08-2011, 04:08 AM   #2
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
If I understand well you want to assign the positional parameters to the array elements. If this is the case you can simply do
Code:
array=("$@")
Then you can check the array length and refer to the array elements using the proper syntax.
 
Old 03-08-2011, 04:32 AM   #3
greengrocer
Member
 
Registered: Aug 2005
Distribution: Ubuntu Intrepid and Meerkat, formerly used Debian 3.1 (Sarge) with Gnome Desktop
Posts: 353

Original Poster
Rep: Reputation: 37
Thanks, I just did a quick read on Arrays and that method might be easiest if I can just get the basics working.

The following:
Code:
#!/bin/bash

array=("$@")
Yields

Quote:
myscript.sh 3: Syntax error: "(" unexpected
Then I tried something simple:
Code:
#!/bin/bash

array=(hello)
Which yielded

Quote:
myscript.sh 3: Syntax error: "(" unexpected

What am I doing wrong with my syntax when using the array() command?
 
Old 03-08-2011, 04:36 AM   #4
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Quote:
Originally Posted by greengrocer View Post
What am I doing wrong with my syntax when using the array() command?
Nothing wrong! Please check which shell you're actually using and show us the output of the following commands:
Code:
readlink -f /bin/bash
bash --version
 
Old 03-08-2011, 04:51 AM   #5
greengrocer
Member
 
Registered: Aug 2005
Distribution: Ubuntu Intrepid and Meerkat, formerly used Debian 3.1 (Sarge) with Gnome Desktop
Posts: 353

Original Poster
Rep: Reputation: 37
Output of readlink -f /bin/bash

Code:
/bin/bash

Output of bash --version

Code:
GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
 
Old 03-08-2011, 05:03 AM   #6
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Well... it sounds good. However I think there is a problem with the fact that Ubuntu uses /bin/dash as the default shell and for some reason the sha-bang #!/bin/bash is skipped. In other words it looks like the script is executed by the dash shell and the array assigment is buggy in some way. Just a guess, but I found confirmation on the Ubuntu forums, here (see in particular post #5). By the way, how did you run the script? Does
Code:
bash scriptname.sh
make a difference?
 
1 members found this post helpful.
Old 03-08-2011, 05:14 AM   #7
greengrocer
Member
 
Registered: Aug 2005
Distribution: Ubuntu Intrepid and Meerkat, formerly used Debian 3.1 (Sarge) with Gnome Desktop
Posts: 353

Original Poster
Rep: Reputation: 37
Yes you're right.

The sha-bang was being skipped when I invoke my script using sh myscript.sh

So instead I tried:

Code:
./myscript.sh
Which worked (but first I had to chmod 755 myscript.sh).

Last edited by greengrocer; 03-08-2011 at 05:15 AM.
 
Old 03-08-2011, 05:27 AM   #8
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Indeed when the shell is invoked as interactive (for example when the standard input is connected to a terminal and you don't use the -c option) the sha-bang is treated as a comment. The question now is: how does /bin/dash manage arrays? What are the differences between the /bin/bash syntax and /bin/dash? I cannot find any exhaustive documentation on the net. Maybe someone here can shed some light.

Edit: I found some information on Greg's Wiki: http://mywiki.wooledge.org/Bashism which simply states that
Quote:
Arrays are not defined by posix (but are present in ksh); there is no easy general workaround for arrays.
but it still doesn't tell anything about the exact dash behaviour.

Last edited by colucix; 03-08-2011 at 05:36 AM.
 
Old 03-08-2011, 05:40 AM   #9
greengrocer
Member
 
Registered: Aug 2005
Distribution: Ubuntu Intrepid and Meerkat, formerly used Debian 3.1 (Sarge) with Gnome Desktop
Posts: 353

Original Poster
Rep: Reputation: 37
Almost there.

My script is:

Code:
#!/bin/bash

array=("$@")
len=${#array[*]}
echo "The array has $len members. They are:"
i=0
while [ $i -lt $len ]; do
	parameter$i=${array[$i]}
        echo "${parameter[$i]}" 
	let i++
done
When I invoke my script using:

Quote:
./myscript.sh alpha bravo charlie
I get the following output:

Code:
The array has 3 members. They are:
./myscript.sh: line 8: parameter0=alpha: command not found

./myscript.sh: line 8: parameter1=bravo: command not found

./myscript.sh: line 8: parameter2=charlie: command not found
What I really want is echo "${parameter[$i]}" to deliver output as:

Code:
The array has 3 members. They are:
alpha
bravo
charlie
Where:
parameter1 = alpha
parameter2 = bravo
parameter3 = charlie


I know I am close to the solution but my knowledge of manipulating variables is weak.
 
Old 03-08-2011, 06:33 AM   #10
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Code:
        parameter$i=${array[$i]}
        echo "${parameter[$i]}"
It's not really clear what you're trying to do here. This code tries to assign scalar variables parameter0, parameter1, parameter2 then it tries to print them as array elements. In any case waht you need is indirect reference where the name of a variable is referenced by another variable. Here is a working example using eval:
Code:
i=1
while [ $i -lt $len ]; do
	eval parameter$i=${array[$i]}
	eval echo \$parameter$i
	let i++
done
Please see http://www.tldp.org/LDP/abs/html/abs-guide.html#IVR for more details about indirect reference.

Anyway, if you need to assign the positional parameters to scalar variables, the array step is superfluous. Here is two alternatives:
Code:
 #!/bin/bash
i=1
while [[ $i -le $# ]]
do
  eval parameter$i=\$$i
  eval echo \$parameter$i
  (( i++ ))
done
or using shift
Code:
#!/bin/bash
i=1
until [[ -z $1 ]]
do
  eval parameter$i=$1
  eval echo \$parameter$i
  shift
  (( i++ ))
done
I would stick with arrays anyway, since indirect reference might be confusing. Furthermore the eval statement can be dangerous in some situations.

Last edited by colucix; 03-08-2011 at 06:46 AM.
 
Old 03-08-2011, 07:49 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,424

Rep: Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823
So I will start with, I am not really sure what the objective is here?
The reason i said this is because unless you need the separate storage, ie array, for another reason, why not just use the positional parameters as they lay?

$# will give you the number of parameters passed in and the same as using say array[1] you can just use $2 (as arrays start at 0 unless otherwise defined).

So to use your current example:
Code:
#!/bin/bash

echo "$# members were passed in. They are:"

for ARG
do
    echo $ARG
done
Output:
Code:
$ ./myscript.sh alpha bravo charlie
3 members were passed in. They are:
alpha
bravo
charlie
 
Old 03-08-2011, 11:38 AM   #12
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Arch
Posts: 3,061

Rep: Reputation: 1268Reputation: 1268Reputation: 1268Reputation: 1268Reputation: 1268Reputation: 1268Reputation: 1268Reputation: 1268Reputation: 1268
Quote:
Originally Posted by colucix View Post
The question now is: how does /bin/dash manage arrays? What are the differences between the /bin/bash syntax and /bin/dash? I cannot find any exhaustive documentation on the net. Maybe someone here can shed some light.

Edit: I found some information on Greg's Wiki: http://mywiki.wooledge.org/Bashism which simply states that
Quote:
Arrays are not defined by posix (but are present in ksh); there is no easy general workaround for arrays.
but it still doesn't tell anything about the exact dash behaviour.
dash doesn't support arrays, it's supposed to be a shell with the minimum number of features needed for POSIX compliance.
 
Old 03-10-2011, 03:20 AM   #13
greengrocer
Member
 
Registered: Aug 2005
Distribution: Ubuntu Intrepid and Meerkat, formerly used Debian 3.1 (Sarge) with Gnome Desktop
Posts: 353

Original Poster
Rep: Reputation: 37
OK, I'm starting to see what you mean about an array perhaps being the most appropriate method for what I want to do because while the array is storing the parameters that were specified when my script is invoked, I can step through the array, locate a parameter and act upon it using while and if loops.
 
Old 03-10-2011, 09:37 AM   #14
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,424

Rep: Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823Reputation: 2823
Quote:
OK, I'm starting to see what you mean about an array perhaps being the most appropriate method for what I want to do because while the array is storing the parameters that were specified when my script is invoked, I can step through the array, locate a parameter and act upon it using while and if loops.
That and the fact that eval is often pronounced 'evil' as it can cause some serious headaches ... especially if it gets out of control.
 
Old 04-11-2011, 04:24 PM   #15
scurveedog
LQ Newbie
 
Registered: May 2009
Posts: 4

Rep: Reputation: 0
maybe a case where you can deal with any or all parameters?

Code:
#!/bin/bash

while test $# -gt 0; do
	case "$1" in
		red)
			echo "$1"
			# code for red param
		shift;;

		green)
			echo "$1"
			# code for green param
		shift;;
		
		blue)
			echo "$1"
			#code for blue param
		shift;;

		*)
			echo "Not in parameter list"
                        # or code to handle case of no or non-listed param
		exit 1;;
	esac
done
as is, the case will exit as soon as a non-listed parameter is found.
 
  


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
Variables and Mkvextract in a bash script and a good resource for bash help? gohmifune Linux - General 9 04-13-2011 09:37 AM
[SOLVED] Variables between shell scripts Potatos Linux - Newbie 1 05-20-2010 10:32 AM
Bash Script: parse active process stderr, strip, dump into variables, use variables TimeFade Programming 1 02-13-2010 07:09 AM
Question about variables in BASH scripts gimpy530 Linux - General 5 11-19-2009 11:02 PM
Importing environment variables into bash scripts JDska55 Linux - Newbie 1 08-11-2009 05:27 PM


All times are GMT -5. The time now is 04:29 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration