Melody Nelson
Melody Nelson

Reputation: 110

How to interpolate a string that was sent as an argument?

I have limited access to the filesystem, and I want to set up universal notification handler call like that:

notificator.sh "apples" "oranges" "There were $(1) and $(2) in the basket"

notificator.sh contents:

#!/bin/sh
echo $3

And get output looking like:

"There were apples and oranges in the basket"

Is it possible and how? I'd prefer if it was a builtin sh solution. I'm actually trying to send the result string ($3) as a message to the telegram bot via curl post param, but tried to simplify the situation.

Upvotes: 5

Views: 3040

Answers (1)

John1024
John1024

Reputation: 113844

With some changes to your $3, we can make this work easily.

First, let's define $1, $2, and $3:

$ set -- "apples" "oranges" 'There were ${one} and ${two} in the basket'

Now, let's force substitutions into $3:

$ one=$1 two=$2 envsubst <<<"$3"
There were apples and oranges in the basket

Notes:

  1. $(1) attempts to run a command named 1 and will likely generate an error even before your script runs. Use ${var} instead.

  2. To get this method to work, we needed to rename the variables in $3.

  3. envsubst is part of the GNU gettext-base package and should be available by default of Linux distributions.

Hat tip to Charles Duffy.

In script form

Consider this script:

$ cat script.sh
#!/bin/sh
echo "$3" | one=$1 two=$2 envsubst

We can execute the above:

$ sh script.sh "apples" "oranges" 'There were ${one} and ${two} in the basket'
There were apples and oranges in the basket

As an alternative (hat tip again to Charles Duffy), we can use a here-doc:

$ cat script2.sh
#!/bin/sh
one=$1 two=$2 envsubst <<EOF
$3
EOF

Running this version:

$ sh script2.sh "apples" "oranges" 'There were ${one} and ${two} in the basket'
There were apples and oranges in the basket

Alternative

The following script does not require envsubst:

$ cat script3.sh
#!/bin/sh
echo "$3" | awk '{gsub(/\$\{1\}/, a); gsub(/\$\{2\}/, b)} 1' a=$1 b=$2

Running this script with our arguments, we find:

$ sh script3.sh "apples" "oranges" 'There were ${1} and ${2} in the basket'
There were apples and oranges in the basket
$ sh script3.sh "apples" "oranges" 'There were ${1} and ${2} in the basket'
There were apples and oranges in the basket

Upvotes: 4

Related Questions