14

At this moment I have:

#!/bin/bash
screen -p 'ScreenName' -x eval 'stuff '"'"$@"'"'\015'
echo eval 'stuff '"'"$@"'"'\015'

But when I call my script as:

# script.sh asd "asd" 'asd'

my arguments passed as: asd asd asd

and I get output:

eval stuff 'asd asd asd'\015

I except a: asd "asd" 'asd'

How I can change my script to pass whole arguments line with all quotes?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Arthur Halma
  • 363
  • 2
  • 3
  • 8

3 Answers3

9

Your shell is not passing the quotes through to the script. If you want to pass quotes, escape them with a backslash:

# ./script.sh asd \"asd\" \'asd\'
teppic
  • 4,535
  • 1
  • 17
  • 17
4
sh -c "screen -x 'ScreenName' -X eval 'stuff \"$@\"\015'"
Mat
  • 51,578
  • 10
  • 158
  • 140
Derek
  • 49
  • 1
2

Note: this does not work in plain shell but in Bash

The only solution is to indicate to your shell that these are not syntax but actual content, like this :

script.sh $'asd "asd" \'asd\''
#         ^^          ^    ^ ^
#         ||          |    | |
#         12          3    3 2

1: prefixing a string by $ change its meaning, allowing to backslash-escape quotes, cf https://unix.stackexchange.com/a/30904/383566
2: enclosing the value between single quotes indicate to the shell that it must be treated as a single argument
3: backslash-escaping the single quote, because it is used as enclosing syntax (see 2)

Proof :

# defining a function to test
> function count_and_print_args() {  # if not using bash, remove the "function"
        echo $#  # print the number of arguments
        for arg in "$@"  # for each of all arguments
        do
                echo "$arg"  # print the argument on a newline
        done;
}
> count_and_print_args
0
> count_and_print_args a b c
3
a
b
c
> count_and_print_args $'asd "asd" \'asd\''
1
asd "asd" 'asd'
Lenormju
  • 121
  • 3