1

I'm trying to insert an argument in the middle of a command with "$@" for learning purposes. I don't know if that's optimal, but it's what I've been trying to do. This is what I have: when I run test.sh foo it runs echo "$@" bar which I was hoping would print foo bar. Instead, it's printing bar foo. I don't know neither if that's expected behavior nor what I should do instead.

test.sh foo
# runs
echo "$@" bar
# which is printing
bar foo

Edit: I had simplified the context and was in reality trying to use "$@" in an alias.

AdminBee
  • 21,637
  • 21
  • 47
  • 71
matticebox
  • 13
  • 4
  • 1
    What does `test.sh` actually contain? If it really contained `echo "$@" bar`, the output of running `./test.sh foo` would be `foo bar`. Note that `test.sh foo` doesn't look for `test.sh` in the current directory unless you've added `.` to `PATH`. Maybe you have another `test.sh` somewhere else and you're running that? – Gilles 'SO- stop being evil' Jul 28 '21 at 21:51
  • @Gilles'SO-stopbeingevil' Okay, so I'll be more specific. If I'm setting up an alias `test='echo "$@" bar'` and I run `test foo` in a terminal, it prints `bar foo`. – matticebox Jul 28 '21 at 21:55
  • 2
    [Aliases vs functions vs scripts](https://unix.stackexchange.com/q/4023/170373) – ilkkachu Jul 28 '21 at 21:59
  • 2
    Aliases don't take arguments into `$@`, just whatever you stick after the alias name ends up at after the expansion, so you end up with `echo "$@" bar foo`. – ilkkachu Jul 28 '21 at 22:00
  • @ilkkachu I see. So, asking as a newbie, a function would be an ideal alternative to what I'm trying to do? – matticebox Jul 28 '21 at 22:14

1 Answers1

2

Aliases are just a simple replacement, they don't take arguments themselves. So if you have alias x='echo "$@" bar'(*), and you run x foo, you end up with

echo "$@" bar foo

i.e. with just the alias name x replaced with the contents and the rest left on in the end. Now, that "$@" is the argument list of the context where x foo was run. Probably your interactive shell, which usually doesn't have anything in the argument list, so the "$@" gets removed. But if you had something in the argument list (positional parameters), they'd be expanded at that position:

$ alias x='echo "$@" bar'
$ set -- args here
$ x foo
args here bar foo

Instead, if you used a function or a script file, that would work. This should print foo bar:

f() {
    echo "$@" bar
}
f foo

as should running something like ./s.sh foo, if s.sh is executable and contains that echo line.

See:

(* test is a standard command, the same as [ .. ], so better not use it for... well, this kind of testing purposes.)

ilkkachu
  • 133,243
  • 15
  • 236
  • 397