LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   a script to give me the last argument !!! (https://www.linuxquestions.org/questions/linux-general-1/a-script-to-give-me-the-last-argument-56689/)

rameshvl 04-25-2003 12:49 AM

a script to give me the last argument !!!
 
Hi

I just want a shell script which gives me the last argument passed.

For example,
if the script script.sh is executed

>script.sh one two three

it must give me "three"

Also,

>script.sh one two "three four"

must give me "three four"

Could u geeks help me ??????

thanks in advance,
rameshvl

m0rl0ck 04-25-2003 01:53 AM

Heres how in perl:

$rnum=$#ARGV;


print @ARGV[$rnum];


The $#ARGV just returns the number of elements in the input array of arguements. Im sure theres a comparable shell function. "man bash" would probably be a good start.

unSpawn 04-25-2003 02:38 AM

I just want a shell script which gives me the last argument passed.
rameshvl, could you show us at least you made *some* effort trying to work it out yourself?

#All supplied args is $@, so # of args is ${#@}

rameshvl 04-25-2003 06:39 AM

Mr. unSpawn,

${#@} gives the no. of arguments ($# also gives this), but what i want is the "value" of last argument.

AND, I DID TRY before posting my problem, and I NEED NOT PROVE IT TO U.

Anyway, Im giving my code below. It is a round-about way of getting the last argument though

Here goes ...

n=$#
c=1
echo -n "LAST ARGUMENT IS "
for k in $*
do
if test $c -eq $n
then
echo $k
fi
c=`expr $c + 1`
done

This gives "three" for

>script.sh one two three

but fails for

>script.sh one two "three four"

thanks for ur suggestion anyway,
rameshvl

unSpawn 04-25-2003 07:46 AM

AND, I DID TRY before posting my problem, and I NEED NOT PROVE IT TO U.
No need to shout, and IMNSHO, you do.
Why? It means we don't need to think for instance about stuff like this being a school project (I personally loathe contributing to those unless ppl tell it up front and match the criteria below). Showing what you did and where it went wrong is also easier cuz we don't have to reinvent the whole wheel again. Plus it's what I hope to be part of minimal netiquette, courtesy, respect or whatever you'd call it amongst LQ members.

Say args=( $@ ), then if you have $# (or ${#args[@]} in this case), then if you don't want to show the 1st 2 args, why not do
for n in $(seq 2 ${#args[@]}); do printf "%s${args[$n]}\n"; done

Btw, due to $IFS in the interactive Bash shell squishing "three four" together won't work.

Mik 04-25-2003 09:18 AM

Well there is a way of getting around the $IFS seperator. You could use the shift to get to the last parmeter. And then just use $1 to extract it. Something like:

#!/bin/bash
shift $(($# - 1))
echo $1

rameshvl 04-28-2003 01:07 AM

Hello

Thanks Mik, it worked !!! Can u suggest me some links where i can learn more abt these stuff ??
and Mr. unSpawn, i got pissed off for the WAY u had put it, not for anything else, I do understand ur intention, but u cud have been more polite (as being a moderator replying a poster atleast). thanx anyway.

thanx all
rameshvl

Mik 04-28-2003 02:42 AM

Well for bash scripting I wouldn't know anything else besides the Advanced Bash Scripting Guide. You can get that at www.tldp.org

unSpawn 04-28-2003 06:17 AM

and Mr. unSpawn, i got pissed off for the WAY u had put it, .*but u cud have been more polite.*thanx anyway.
LOL! And I thought subtly posting it as a question saying "could" instead of "must" should do the trick...

Anyway, just posted these links in another thread.

nayakss 12-29-2008 06:20 AM

The best answer would be

echo ${!#}

Thanks,
S S Nayak

frenchn00b 12-29-2008 08:55 AM

Quote:

Originally Posted by Mik (Post 287142)
Well there is a way of getting around the $IFS seperator. You could use the shift to get to the last parmeter. And then just use $1 to extract it. Something like:

#!/bin/bash
shift $(($# - 1))
echo $1

Does it work with ps aux ?

Code:

ps aux | lastargument

colucix 12-29-2008 09:07 AM

You are resurrecting an almost 6 years old thread! frenchn00b, if you want to print the last field of a line passed through a pipe, just use awk '{print $NF}'.

David the H. 12-29-2008 10:58 AM

Quote:

Originally Posted by colucix (Post 3390389)
You are resurrecting an almost 6 years old thread!

And for that I'm thankful. Because I'm able to learn something new from reading it. :D

I'm still trying to understand "${!#}" though. I've been looking through the Advanced Bash Scripting Guide, but I haven't been able to find any specific reference explaining what it does exactly. Could someone explain it to me?

PTrenholme 12-29-2008 11:15 AM

Quote:

Originally Posted by David the H. (Post 3390506)
And for that I'm thankful. Because I'm able to learn something new from reading it. :D

I'm still trying to understand "${!#}" though. I've been looking through the Advanced Bash Scripting Guide, but I haven't been able to find any specific reference explaining what it does exactly. Could someone explain it to me?

Look in info bash under "Basic Shell features -> Shell Expansions -> Shell Parameter Expansion" or in the index under "!" for details.

colucix 12-29-2008 11:19 AM

Quote:

Originally Posted by David the H. (Post 3390506)
I'm still trying to understand "${!#}" though. I've been looking through the Advanced Bash Scripting Guide, but I haven't been able to find any specific reference explaining what it does exactly. Could someone explain it to me?

To me it is simply the "new" notation for indirect referencing, introduced in Bash version 2:
Code:

${!variable}
instead of the classic \$$var notation. Assumed that $# is a special variable that gives the number of arguments, ${!#} is a reference to the last argument. Very similar to $NF in awk.

David the H. 12-29-2008 12:29 PM

Thank you very much. Actually, I finally found it for myself not long after I posted. There's a good example of it on the "special variables" page, referencing positional variables. But by the time I came back, I had two answers. You guys are fast. :)

I see now that it's an interesting use of indirect referencing...it outputs the value of the last positional variable, as given by "$#". Easy once you know what the parts mean.

But now why is it when I try it with the old syntax, and use 'echo \$$#', it doesn't work? It only give me the output "$3" (for example) when I try it, instead of the actual value.

Edit: Found the reason, I think. You need to eval the older notation before it will work. 'eval echo \$$#' seems to do the trick. I still don't quite understand exactly why you need to do this though.

colucix 12-29-2008 12:44 PM

Quote:

Originally Posted by David the H. (Post 3390619)
But now why is it when I try it with the old syntax, and use 'echo \$$#', it doesn't work? It only give me the output "$3" (for example) when I try it, instead of the actual value.

You have to use the old syntax for indirect reference in conjunction to the eval built-in. Running
Code:

echo \$$#
the shell substitutes the variable $# with the actual number of arguments and interprets the escaped $ sign as a litteral $. Using eval instead
Code:

eval echo \$$#
first the shell does the above substitution, then passes the resulting string "echo $3" to the eval bult-in, which in turn causes the substitution of $3 with its actual value.

Edit: you are faster than us, now! :)

David the H. 12-29-2008 12:59 PM

Thank you for the explanation. I kind of suspected that that was what was happening, but I wasn't sure. I'm still not quite clear on exactly what things like eval do sometimes.

I suppose the new ${!} notation bypasses all that and just grabs the value directly then? It's certainly easier and much more intuitive in any case.

David the H. 12-29-2008 01:02 PM

Deleted. Accidentally duplicated my post.


All times are GMT -5. The time now is 10:56 PM.