hexacyanide
hexacyanide

Reputation: 91609

Bash: Passing a variable into a script that has spaces

I currently have a bash script. It looks like this:

#!/bin/bash

case "$1" in
    sendcommand)
        do X with $2
        exit
        ;;
esac

How would I send all of command this command with spaces into $2 without command acting as $3, with as $4 and so on? Is there something like PHP or Javascript's encodeURI for bash?

Upvotes: 1

Views: 294

Answers (3)

Jonathan Leffler
Jonathan Leffler

Reputation: 753475

Enclose it in double quotes:

do_X_with "$2"

The double quotes preserve the internal spacing on the variable, including newlines if they are in the value in the first place. Indeed, it is important to understand the uses of double quotes with "$@" and "$*" too, not to mention when using bash arrays.

You can't easily have a command called do because the shell uses do as a keyword in its loop structure. To invoke it, you would have to specify a path to the command, such as ./do or $HOME/bin/do.


But $2 is "this" and the OP wants it to be "this command with spaces".

OK. We need to review command line invocations and desired behaviours. Let's assume that the script being executed is called script. Further, that command being executed is othercommand (can't use command; that is a standard command).

Possible invocations include:

  • script sendcommand "this command with spaces"
  • script sendcommand 'this command with spaces'
  • script sendcommand this command with spaces

The single-quote and double-quote invocations are equivalent in this example. They wouldn't be equivalent if there were variables to be expanded or commands to be invoked inside the argument lists.

It is possible to write script to handle all three cases:

#!/bin/bash

case "$1" in
    sendcommand)
        shift
        othercommand "$*"
        exit
        ;;
esac

Suppose that the invocation encloses the arguments in quotes. The shift command removes $1 from the argument list and renumbers the remaining (single) argument as $1. It then invokes othercommand with a single string argument consisting of the contents of the arguments concatenated together. If there were several arguments, the contents would be separated by a single 'space' (first character of $IFS).

Suppose that the invocation does not enclose the arguments in quotes. The shift command still removes $1 (the sendcommand) from the argument list, and then space separates the remaining arguments as a single argument.

In all three cases, the othercommand sees a single argument that consists of "this command with spaces" (where the program does not see the double quotes, of course).

Upvotes: 2

k107
k107

Reputation: 16440

You also have to call your script with the second argument in quotes too

./scriptname sendcommand "command with spaces"

Your script should look like this

#!/bin/bash

case "$1" in
    sendcommand)
        something "$2"
        exit
        ;;
esac

Upvotes: 6

fork0
fork0

Reputation: 3461

You can just use double quotes:

do X with "$2"

Upvotes: 2

Related Questions