Prototype
Prototype

Reputation: 114

Add all arguments except first to a string

Trying to parse all arguments to one string but my code is only giving me errors that it can't find i:

test: line 3: =: command not found
test: line 7: [i: command not found
test: line 7: [i: command not found
test: line 7: [i: command not found
test: line 7: [i: command not found
test: line 7: [i: command not found

Code bellow

#!/bin/sh

$msg=""

for i in $@
do
if [i -gt 1]; then
    msg="$msg $i"
fi
done

EDIT: thx for all the help, got it to work. My final solution if anyones interested:

#!/bin/sh

args=""
for i in "${@:2}"
do
    args="$args $i"
done

Upvotes: 0

Views: 2276

Answers (3)

chepner
chepner

Reputation: 531708

You don't actually need a loop for your specific output (assuming a single string is actually the correct output):

args="${@:2}"  # Use @ instead of * to avoid IFS-based surprises

However, if you plan on iterating over the arguments later, a flat string is the wrong approach. You should be using an array:

args=( "${@:2}" )

Upvotes: 2

paxdiablo
paxdiablo

Reputation: 881993

Your specific error messages are showing up because:

  • assigning to a variable is not done with the $ character as in $msg="", instead you should be using msg=""; and

  • [ is actually a command, one that should be separated from other words by white space, so that the shell doesn't think you're trying to execute some mythical [i command.

However, you have a couple of other problems. The first is that the value of i needs to be obtained with $i, not just i. Using i on its own will give you an error along the lines of:

-bash: [: i: integer expression expected

because i itself is not a numeric value.

Secondly, neither i nor $i is going to be an index that you can compare with 1, so your $i -gt 1 expression will not work. The word $i will expand to the value of the argument, not its index.


However, if you really want to process all but the first element of your argument list, bash has some very C-like constructs which will make your life a lot easier:

for ((i = 2; i <= $#; i++)) ; do   # From two to argc inclusive.
    echo Processing ${!i}
done

Running that with the arguments hello my name is pax, will result in:

Processing my
Processing name
Processing is
Processing pax

For constructing a string containing those arguments, you could use something like:

msg="$2"                           # Second arg (or blank if none).
for ((i = 3; i <= $#; i++)) ; do   # Append all other args.
    msg="$msg ${!i}"
done

which will give you (for the same arguments as above):

[my name is pax]

Although, in that case, there's an even simpler approach which doesn't involve any (explicit) loops at all:

msg="${@:2}"

Upvotes: 3

Nidhoegger
Nidhoegger

Reputation: 5232

[ is just (more or less) an alias for test, so you should use it like a regular command. What I want to say is, that you need whitespaces before and after [ like this:

if [ $i -gt 1 ]; then

Also you forgot the $ before i in the if clause.

Upvotes: 1

Related Questions