How to send variable to an inline shell-script?

46,128

Solution 1

Either use export to turn it into an environment variable, or pass it directly to the command.

VAR="Test" sh -c 'echo "Hello $VAR"'

VAR="Test"
export VAR
sh -c 'echo "Hello $VAR"'

Avoid using double quotes around the shell code to allow interpolation as that introduces command injection vulnerabilities like in:

sh -c " echo 'Hello $VAR' "

causing a reboot if called when $VAR contains something like ';reboot #

Solution 2

Here's yet another way to pass variables to sh -c (as positional arguments):

{
VAR="world"
VAR2='!'
sh -c 'echo "Hello ${0}${1}"' "$VAR" "$VAR2"
}

Solution 3

If you don't want to export them as environment variables, here's a trick you could do. Save your variabe definition to a file .var_init.sh and source it in your sub-shell like this:

.var_init.sh

VAR="Test"

from the command line:

sh -c ". .var_init.sh && echo \$VAR" # Make sure to properly escape the '$'

This way, you only set your variables at the execution of your subshell.

Solution 4

If you're using sudo sh -c, the environment variables are not passed along, but you can get around it by using the --preserve-env argument:

export VAR="test for exporting"
sudo --preserve-env=VAR sh -c 'echo "This is a $VAR"'

This passes along just the variables you need rather than using sudo -E which passes along your entire set of environment variables. From Sudo Manual:

--preserve-env=list Indicates to the security policy that the user wishes to add the comma-separated list of environment variables to those preserved from the user's environment. The security policy may return an error if the user does not have permission to preserve the environment.

Or, you could assign it directly as:

export VAR="test for exporting"
sudo VAR1="$VAR" sh -c 'echo "This is a $VAR1"'
Share:
46,128

Related videos on Youtube

kjartan
Author by

kjartan

I am a software engineer passionate about code and human interactions around it. I like to work with great people, learn and get things done. You can read more about me on my blog or on my GitHub profile. Here are some projects I'm working on: bref.sh: deploy PHP on AWS Lambda to create serverless applications PHP-DI - Dependency injection library for PHP externals.io @matthieunapoli

Updated on September 18, 2022

Comments

  • kjartan
    kjartan almost 2 years

    I run the following script:

    VAR="Test"
    sh -c 'echo "Hello $VAR"'
    

    But I get:

    # ./test.sh
    Hello
    

    How can I send the variable VAR of my script to the shell created with sh -c '...'?

  • kjartan
    kjartan over 12 years
    Not really practical (I have several variables, and I don't want them to be environment variables), but it works, thanks!
  • Osama khodroj
    Osama khodroj over 12 years
    @Matthieu: They are only set as environment variables for the children of your process, if that's what worries you.
  • Kedar Vaidya
    Kedar Vaidya over 12 years
    Just FYI, You can also do export var="Test" in one line.
  • Peter.O
    Peter.O over 12 years
    (+1) To keep it more in line with the normal $1 $2 expectation for script variables, it can have a dummy value for $0. This will allow $@ to work as expected, eg. sh -c 'echo "Hello $@"' _ "$VAR" "$VAR2" `
  • kjartan
    kjartan over 12 years
    @Piskvor well thank you for the precision, that's perfect then.
  • Stéphane Chazelas
    Stéphane Chazelas over 11 years
    @Peter.O Rather than using "_", I would use "sh" or a sensible name to give to that command, since that $0 is displayed in the error/warning messages by the shell.
  • Kusalananda
    Kusalananda about 6 years
    ... or ENV=.var_ini.sh sh -c '...'
  • Stéphane Chazelas
    Stéphane Chazelas almost 5 years
    Note that if that .var_init.sh is expected to be looked for in the current directory (as opposed to $PATH), it should be written . ./var_init.sh