Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can a command-line argument containing a dot (.) be passed? Are there any escape sequences for capturing characters like dot?

The following invocation of a bash-script from the shell does not work:

# ./deploy.sh input.txt
./deploy.sh: line 9: input.txt: syntax error in expression (error token is ".txt")

I have tried the following:

  1. backslash
  2. quote
  3. double quotes
  4. ./deploy.sh input (this works)

EDIT

Take this use-case:

  1. I have 3 files: server.jar client.jar gui.jar
  2. I need to scp them from a source to a dest
  3. source dir: login1@host1:/home/xyz/deploy/
  4. dest dir: login2@host2: /data/apps/env/software/binary/

Solution:

  1. Read artifacts to be copied into an array from the command-line
  2. create dest path and source path strings by using the correct directory prefixes
  3. use a for loop to scp each artifact (having figured out the paths)

Here's the simple script which is doing 1 (read artifacts into an array):

#!/bin/bash
declare -a artifacts
for i
do
artifacts[i]=$i
echo ${artifacts[i]}
done

Execution1

-bash-3.00$ ./simple.sh arg1 arg2 arg3
arg1
arg2
arg3

Execution2

-bash-3.00$ ./simple.sh arg1.txt arg2.txt arg3.txt
./simple.sh: line 7: arg1.txt: syntax error in expression (error token is ".txt")
share|improve this question
8  
There is nothing special about dots in bash; this sounds like an issue with your script deploy.sh and we would need to see it to know what it's doing and how (if at all) to change it. –  geekosaur May 11 '12 at 14:31
2  
You should show us deploy.sh. –  cjc May 11 '12 at 14:35
2  
What is line 9? :-) –  Mikel May 11 '12 at 14:40
4  
Woah! Put your code in the question. Makes reading it much easier. –  Mikel May 11 '12 at 14:44
2  
We don't need to continue in chat. You just need you to put enough information in the question so we can reproduce your problem. Which you have now done. –  Mikel May 11 '12 at 15:13
show 5 more comments

2 Answers

up vote 8 down vote accepted

You need to use declare -A instead of declare -a. You are clearly using associative arrays with arbitrary string arguments as indices, but declare -a is only for integer indexed arrays. arg.txt does not evaluate to a valid integer, hence your error.

Edit

You seem to be using bash version 3. Unfortunately, associative arrays are not available until version 4. I recommend you post a sanitized version of your original deploy.sh script with sensitive personal information removed so you can get ideas from other people about alternative approaches.

Edit 2

Just to summarize a bit of exchange in the chat:

The easiest way to do some action over all the arguments is to just iterate over them with a for loop:

    for arg; do
        scp login1@host1:"$arg" login2@host2:/dest/
    done

Remember to double-quote all instances of "$arg". You do not need to put the arguments in an array yourself, as they already exist in the array $@, which is what for uses by default when you don't give an explicit in list....

share|improve this answer
add comment

That error happens any time you try to use a string where a number was expected.

For example

$((input.txt))

will cause the same error to be printed.

In your case, it turns out you were assigning to an array which uses a numeric index.

jw013 rightly explains you need to do declare -A (uppercase A) for your example to work.

The reason why:

When assigning to an array element, you would normally write

array[0]=foo
array[1]=bar

but you can also write any arithmetic expression as the key, e.g.

array[0+0]=foo
array[1+0]=bar

so the shell is seeing

array[input.txt]=input.txt

trying to convert it to a number like

$((input.txt))

and failing.

The reason the dot is confusing and that arguments without a dot seem to work is that

$((input))

is actually a valid number.

bash sees input, decides it's a valid variable name, sees that the variable is unset, and replaces it with 0.

Compare that to input.txt, which is not a valid variable name, because variable names can't contain dots!

To avoid this confusing behavior, you can use

set -u

then any time you try to use a variable that doesn't exist, you'll get an error, e.g.

set -u
artifacts[arg1]=arg1

prints the error

scriptname: line number: arg1: unbound variable
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.