1

I'm writing shell(bash) script like this:

output_function()
{
    for i in "$@"
    do
        echo $i
    done
}

process_funtion()
{
    string=process some thing
    output_function $string
}

for example, after process some thing, string is

i am line 1
i am line 2

I want to print these 2 line as it is, but actually I got

i
am
line
1
i
am
line
2

Also this NOT work:

#!/bin/bash

output()
{
    printf '%s\n' "$@"
}

output `ifconfig`

result is:

...
2000
inet6
fe80::6de5:743c:addd:7c5a%utun0
prefixlen
64
scopeid
0xa
nd6
options=201<PERFORMNUD,DAD>

And this NOT work also:

#!/bin/bash

output()
{
    printf '%s\n' "$*"
}

output `ifconfig`

result is all in one line.

how to fix this? thank you~

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
batmancn
  • 457
  • 3
  • 15
  • The "$@" is a special variable that creates a *list* of parameters that are separated by spaces. I think $* may do what you want or remove the quotes and use $@. – Kevin Jul 24 '17 at 04:07
  • No, both $@ and $* does NOT work. – batmancn Jul 24 '17 at 04:19
  • First `output` and `output_function` are not the same name. Assuming that's fixed, `for i in "$*"` (doublequotes and dollar-asterisk) will put all the passed arguments into one value, hence one `echo` and one line. But the passed arguments from `output $string` have already had all whitespace (particularly newlines) reduced to a single space, and any wildcards expanded (or dropped, if unmatched with `nullglob` set), so this is not 'as is'. You probably want `output "$line"` and `output(){ echo "$1"; }` (dollar-one) – dave_thompson_085 Jul 24 '17 at 06:06
  • `printf '%s\n' "$@"` and then call `output "$(ifconfig)"` – David C. Rankin Jul 24 '17 at 07:57

2 Answers2

2

You need to enclose the function arguments in double quotes to prevent word splitting:

output "$string"

instead of

output $string

And you don't really need a loop to print the contents of $@, you could simply write:

printf '%s\n' "$@"

See also:

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • 1
    Similarly, if you do use `echo`, use `echo "$i"` instead of `echo $i`. Having variable references occur outside of double-quotes is usually a mistake. (There are some situations where it's ok, but IMO keeping track of them is more trouble than it's worth -- just use double-quotes and don't worry about it.) – Gordon Davisson Jul 24 '17 at 05:36
  • That NOT work under bash-3.2, refer to the result I post above. – batmancn Jul 24 '17 at 06:25
  • @batmancn It does work under bash-3.2 -- did you use `output "$(ifconfig)"`? – David C. Rankin Jul 24 '17 at 07:58
1

In your example:

output()
{
    printf '%s\n' "$*"
}

output `ifconfig`

the result of ifconfig also needs to be quoted, otherwise the result will be split into multiple arguments (using $IFS) before being passed to the function. So

output "`ifconfig`"

should do.

See Bash Reference Manual: 3.4.2 Special Parameters for using $* and $@ correctly and the difference between both.

flederwiesel
  • 447
  • 1
  • 9
  • 17