1

I wrote following Go code.

package main

import (
  "fmt"
  "os"
  "strings"
)

func main() {
  fmt.Println(os.Args)
}

Then compiled it...

$ go build -o out

And created following script a.sh:

#! /bin/bash

set -eu

./out "--opt1" "$@"

Then run a.sh and the result is:

$ a.sh hoge --foo bar
[./out --opt1 hoge --foo bar ]

I want to get $@ as string. I expected [./out --opt1 "hoge --foo bar" ] as a result.

However they are splitted to array elements (by whitespace or $IFS?). Is there any idea to get $@?

Andrea Corbellini
  • 17,339
  • 3
  • 53
  • 69
Jumpei Ogawa
  • 518
  • 1
  • 7
  • 18
  • For most purposes, the behavior you seem to be seeking is exactly the wrong behavior. If it's really what you want, `"$*"` is the ticket; but it's hard to imagine a situation where the possible benefits (which are however unclear to me) would outweigh the surprise to the user. – tripleee Apr 18 '16 at 11:53

2 Answers2

3

You might want to use "$*" instead.

Here's an example:

The function f1 uses "$@" to print its arguments, while f2 uses "$*" to do the same.

f1() { printf '<%s>\n' "$@"; }
f2() { printf '<%s>\n' "$*"; }

Notice the differences in their output:

$ f1 a b c
$ <a>
$ <b>
$ <c>
$ f2 a b c
$ <a b c>

The difference between $@ and $*:

  • Without double quotes (don't do this!): There is no difference.

  • With double quotes: "$@" expands to each positional parameter as its own argument: "$1" "$2" "$3"..., while "$*" expands to the single argument "$1c$2c...", where 'c' is the first character of IFS.

Rany Albeg Wein
  • 3,304
  • 3
  • 16
  • 26
  • There is a note about $* here http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html / The implementation of "$*" has always been a problem and realistically should have been replaced with the behavior of "$@". In almost every case where coders use "$*", they mean "$@". "$*" Can cause bugs and even security holes in your software. – fzerorubigd Apr 18 '16 at 11:33
  • 2
    @fzerorubigd You're partially correct. The problem is that you didn't read the question before posting this comment. – Rany Albeg Wein Apr 18 '16 at 11:35
  • I read it, I think suggesting this is not a good idea, when there is other answer available to this. – fzerorubigd Apr 18 '16 at 11:37
  • @fzerorubigd OK. Post a better answer. – Rany Albeg Wein Apr 18 '16 at 11:38
  • I think there is better answer for this available in bash world :) . my way is to change the go code too. simply using "--" as separator like all other bash utilities. for example there is no normal way (without -- ) to create a directory with name -rf in bash, unless using "mkdir -- -rf" why not pass the $@ after -- and then extract it in go code and join it? – fzerorubigd Apr 18 '16 at 11:45
  • @fzerorubigd Cool. OP might like to hear about your solution and maybe even consider using it. I do not want to open a broad discussion in the comments section. – Rany Albeg Wein Apr 18 '16 at 11:49
  • Thanks. "$*" solved my issue, but I decided to use -- this time. – Jumpei Ogawa Apr 19 '16 at 05:30
1

Go Code

package main

import (
    "fmt"
    "os"
)   

func main() {
    for i, arg := range os.Args {
        fmt.Printf("Args[%d] = %s\n", i, arg)
    }
}

Bash Code

#! /bin/bash

set -eu

./out "--opt1" "$*"

Output

$ ./a.sh hoge --foo bar
Args[0] = ./out
Args[1] = --opt1
Args[2] = hoge --foo bar

Explanation

3.2.5. Special parameters of the Bash Guide for Beginners states:

  • $* — Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable.
  • $@ — Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word.

The implementation of "$" has always been a problem and realistically should have been replaced with the behavior of "$@". In almost every case where coders use "$", they mean "$@". "$*" Can cause bugs and even security holes in your software.

Matthew Rankin
  • 457,139
  • 39
  • 126
  • 163
  • the [tldp](http://www.tldp.org/LDP/Bash-Beginners-Guide/html/Bash-Beginners-Guide.html) Bash guide is outdated, and in some cases just plain wrong. Instead, I suggest to use [Bash Guide](http://mywiki.wooledge.org/BashGuide) by [Lhunath](http://mywiki.wooledge.org/Lhunath) and [Greycat](http://mywiki.wooledge.org/GreyCat). – Rany Albeg Wein Apr 18 '16 at 14:06