LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 04-28-2024, 12:09 AM   #1
Linunix
Member
 
Registered: May 2005
Location: Germany
Posts: 58

Rep: Reputation: 15
Bash Arguments Problem


Hello
Encountered a problem concerning script arguments in bash (likely also sh). Arguments to a call of a script get unboxed in the sense that surrounding quotation characters '"' are removed in the values you can use inside of the script, namely as $1, $2 $* etc. These quotations are used e.g. when an argument contains blank characters. So far so good, but if you need to pass some or all script arguments on to some other program call inside the script, what will you do?

If you don't know the exact number of arguments, you would be inclined to use "$*" as single argument to Z (your inside program call). But this loses the brackets '"' and the call fails due to incorrect argument transmission. You can use "$1" "$2" "$3" etc. as arguments to Z but this fixes the number of arguments, which is not always a tolerable error.

What is in demand is a way to transmit the original arguments to a script on to a subprogram. I have not found such a way. Anybody has a solution?
 
Old 04-28-2024, 01:24 AM   #2
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196
That is what "$@" is for. From man bash:

Code:
@     Expands to the positional parameters, starting from one.  In contexts where word  splitting
      is performed, this expands each positional parameter to a separate word; if not within dou‐
      ble quotes, these words are subject to word splitting.  In contexts where word splitting is
      not  performed, this expands to a single word with each positional parameter separated by a
      space.  When the expansion occurs within double quotes, each parameter expands to  a  sepa‐
      rate  word.   That  is, "$@" is equivalent to "$1" "$2" ...  If the double-quoted expansion
      occurs within a word, the expansion of the first parameter is  joined  with  the  beginning
      part  of the original word, and the expansion of the last parameter is joined with the last
      part of the original word.  When there are no positional parameters, "$@" and $@ expand  to
      nothing (i.e., they are removed).
 
Old 04-28-2024, 02:28 AM   #3
Linunix
Member
 
Registered: May 2005
Location: Germany
Posts: 58

Original Poster
Rep: Reputation: 15
Thanks!
I read that before but I wonder if it's implemented because it can't produce any difference to "$*" with "$@" or ""$@"".
For instance I tried
Code:
echo "cmdline \$@ = "$@""
echo "$@" > clfile
cat clfile
but I don't receive any quoted arguments.
 
Old 04-28-2024, 11:51 AM   #4
lvm_
Member
 
Registered: Jul 2020
Posts: 948

Rep: Reputation: 339Reputation: 339Reputation: 339Reputation: 339
You shouldn't, quotes are means to alter processing of certain characters, not argument delimiters. The difference between "$@" and "$*" is noticeable only when passing arguments to a function or process.
 
Old 04-28-2024, 01:59 PM   #5
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196
Quote:
Originally Posted by Linunix View Post
Thanks!
I read that before but I wonder if it's implemented because it can't produce any difference to "$*" with "$@" or ""$@"".
For instance I tried
Code:
echo "cmdline \$@ = "$@""
echo "$@" > clfile
cat clfile
but I don't receive any quoted arguments.
Ah, I think I understand better what you are trying to do now.

The quotes themselves have meaning only for the shell which encounters them (i.e. the shell that invokes the first script), and as already pointed out, should not be thought of as delimiters so much as an escaping mechanism. Again, from man bash:

Code:
QUOTING
       Quoting  is  used to remove the special meaning of certain characters or words to
       the shell.
        ...
       There are three quoting mechanisms: the escape character, single quotes, and dou‐
       ble quotes.
So the first application never sees the quotes themselves (their special meaning was for the invoking shell), the target script only receives the (previously escaped) values. When you then pass those values on within your script such as via "$@", you pass on the received meaning of those parameters, but not any escaping mechanism used to allow you to receive them. If the original parameter was empty (i.e. nothing ordinary and nothing escaped) then you pass on that same nothing to the next application. The quotes in "$@" again have meaning to the current shell, not the shell in which the constructed command is executed, and not to the target script.

If for some reason you really needed to pass something instead of nothing for those received empty parameters, it would be up to your first application to escape the nothings it had received into something that can be passed along to the next application, perhaps by finding the empty ones and replacing them with a set of escaped quotes, \"\". Then the current shell would ignore the special meaning of quotes, the shell in which the next command is executed would see the empty quotes as an escaped nothing and pass along an empty parameter, and the target script would receive the meaning of an empty positional parameter.

Hope that makes sense!

Last edited by astrogeek; 04-28-2024 at 04:09 PM. Reason: clarity
 
Old 04-29-2024, 01:58 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,945

Rep: Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325Reputation: 7325
the quotes are not part of the argument itself, they are just part of the command line.
bash (or sh, zsh) will evaluate the text you entered. The string between " " will be kept together, it will be a single argument, but without " it will be split by whitespaces.
' and " works differently, would be nice to check the documentation about quotation.
If you want to inspect the current arguments you can use something like this:
Code:
for i in "$@"
do
    ((++j)
    echo "${j}:${i}<<<" # this is to see the end of the value
done
you can use $* instead of $@ and you will see the difference
you can check this page too: https://tldp.org/LDP/abs/html/
also I recommend shellcheck to make your script even better
 
Old 04-30-2024, 12:35 PM   #7
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207
echo prints a space between its arguments, not good for distinguishing them from embedded space characters.
Yes a for loop can do it, or printf:
Code:
printf "%s\n" "$@"
Code:
printf '"%s" ' "$@"
Unlike the * (that concatenates to a string), the @ keeps the individuals. The same is for arrays:
Code:
arr=( "$@" )
printf "%s\n" "${arr[@]}"
Change any of the @ to * and it "spoils" to a string (not revertible - information is lost).

Last edited by MadeInGermany; 04-30-2024 at 12:40 PM.
 
  


Reply

Tags
bash



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 On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with analyzing command line arguments: bash shell script newbiecolonopenparens Linux - Newbie 7 05-24-2012 08:29 PM
Problem With Arguments Test in Bash Script dcparris Linux - Software 8 03-20-2012 07:07 AM
[Bash] Problem with arguments in loop en1du Programming 6 10-26-2011 06:53 AM
bash wrapper arguments problem ... khanrockz Programming 3 06-15-2007 11:38 AM
BASH says "too many arguments" in terminal tmitch70377 Linux - Newbie 4 12-06-2003 05:19 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

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