Bash – Passing a bash command-line argument containing a dot

bashcommand lineescape-charactersshell-script

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")

Best Answer

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....

Related Question