Passing variables in remote ssh command

前端 未结 7 1664
余生分开走
余生分开走 2020-12-04 11:59

I want to be able to run a command from my machine using ssh and pass through the environment variable $BUILD_NUMBER

Here\'s what I\'m trying:



        
相关标签:
7条回答
  • 2020-12-04 12:11

    (This answer might seem needlessly complicated, but it’s easily extensible and robust regarding whitespace and special characters, as far as I know.)

    You can feed data right through the standard input of the ssh command and read that from the remote location.

    In the following example,

    1. an indexed array is filled (for convenience) with the names of the variables whose values you want to retrieve on the remote side.
    2. For each of those variables, we give to ssh a null-terminated line giving the name and value of the variable.
    3. In the shh command itself, we loop through these lines to initialise the required variables.
    # Initialize examples of variables.
    # The first one even contains whitespace and a newline.
    readonly FOO=$'apjlljs ailsi \n ajlls\t éjij'
    readonly BAR=ygnàgyààynygbjrbjrb
    
    # Make a list of what you want to pass through SSH.
    # (The “unset” is just in case someone exported
    # an associative array with this name.)
    unset -v VAR_NAMES
    readonly VAR_NAMES=(
        FOO
        BAR
    )
    
    for name in "${VAR_NAMES[@]}"
    do
        printf '%s %s\0' "$name" "${!name}"
    done | ssh user@somehost.com '
        while read -rd '"''"' name value
        do
            export "$name"="$value"
        done
    
        # Check
        printf "FOO = [%q]; BAR = [%q]\n" "$FOO" "$BAR"
    '
    

    Output:

    FOO = [$'apjlljs ailsi \n ajlls\t éjij']; BAR = [ygnàgyààynygbjrbjrb]
    

    If you don’t need to export those, you should be able to use declare instead of export.

    A really simplified version (if you don’t need the extensibility, have a single variable to process, etc.) would look like:

    $ ssh user@somehost.com 'read foo' <<< "$foo"
    
    0 讨论(0)
  • 2020-12-04 12:13

    Variables in single-quotes are not evaluated. Use double quotes:

    ssh pvt@192.168.1.133 "~/tools/run_pvt.pl $BUILD_NUMBER"
    

    The shell will expand variables in double-quotes, but not in single-quotes. This will change into your desired string before being passed to the ssh command.

    0 讨论(0)
  • 2020-12-04 12:14

    As answered previously, you do not need to set the environment variable on the remote host. Instead, you can simply do the meta-expansion on the local host, and pass the value to the remote host.

    ssh pvt@192.168.1.133 '~/tools/run_pvt.pl $BUILD_NUMBER'
    

    If you really want to set the environment variable on the remote host and use it, you can use the env program

    ssh pvt@192.168.1.133 "env BUILD_NUMBER=$BUILD_NUMBER ~/tools/run_pvt.pl \$BUILD_NUMBER"
    

    In this case this is a bit of an overkill, and note

    • env BUILD_NUMBER=$BUILD_NUMBER does the meta expansion on the local host
    • the remote BUILD_NUMBER environment variable will be used by
      the remote shell
    0 讨论(0)
  • 2020-12-04 12:16

    It is also possible to pass environment variables explicitly through ssh. It does require some server-side set-up through, so this this not a universal answer.

    In my case, I wanted to pass a backup repository encryption key to a command on the backup storage server without having that key stored there, but note that any environment variable is visible in ps! The solution of passing the key on stdin would work as well, but I found it too cumbersome. In any case, here's how to pass an environment variable through ssh:

    On the server, edit the sshd_config file, typically /etc/ssh/sshd_config and add an AcceptEnv directive matching the variables you want to pass. See man sshd_config. In my case, I want to pass variables to borg backup so I chose:

    AcceptEnv BORG_*
    

    Now, on the client use the -o SendEnv option to send environment variables. The following command line sets the environment variable BORG_SECRET and then flags it to be sent to the client machine (called backup). It then runs printenv there and filters the output for BORG variables:

    $ BORG_SECRET=magic-happens ssh -o SendEnv=BORG_SECRET backup printenv | egrep BORG
    BORG_SECRET=magic-happens
    
    0 讨论(0)
  • 2020-12-04 12:18

    The list of accepted environment variables on SSHD by default includes LC_*. Thus:

    LC_MY_BUILDN="1.2.3" ssh -o "SendEnv LC_MY_BUILDN" ssh-host 'echo $LC_MY_BUILDN'
    1.2.3
    
    0 讨论(0)
  • 2020-12-04 12:23

    If you use

    ssh pvt@192.168.1.133 "~/tools/run_pvt.pl $BUILD_NUMBER"
    

    instead of

    ssh pvt@192.168.1.133 '~/tools/run_pvt.pl $BUILD_NUMBER'
    

    your shell will interpolate the $BUILD_NUMBER before sending the command string to the remote host.

    0 讨论(0)
提交回复
热议问题