Uzak ssh komutunda değişkenleri iletme


103

Makinemden ssh kullanarak bir komut çalıştırabilmek ve ortam değişkenini geçebilmek istiyorum $BUILD_NUMBER

İşte denediğim şey:

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

$BUILD_NUMBER ssh çağrısı yapan makinede ayarlanır ve değişken uzak ana bilgisayarda bulunmadığından, alınmaz.

Değerini nasıl aktarırım $BUILD_NUMBER?


1
Hudson ile ilgisi yok, etiketi kaldırdı. (Hudson sadece değişkeni yaratır)
Peter Schuetze

Yanıtlar:


197

Eğer kullanırsan

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

onun yerine

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

Kabuğunuz $BUILD_NUMBERkomut dizesini uzak ana bilgisayara göndermeden önce enterpolasyon yapacaktır.


8
Eğer birisi tırnak içinde yer alan komutun yerel olarak değerlendirilmemesi için tek tırnak kullanması ZORUNLUysa, o zaman "$ VARIABLE" kullanmalıdır. Örnek: ssh pvt@192.168.1.133 '~ / tools / run_pvt.pl "' $ BUILD_NUMBER '"'
dr.doom

3
bash'ın tek ve çift tırnaklarla farklı tepki verdiğini bilmiyordum. Teşekkürler!
silgon

1
linux çekirdek geliştiricileri cehennemde yanmalı
goldstar

@goldstar, kabuktaki tek alıntı ve çift tırnak davranışı arasındaki farkın Linux'tan on yıl önce olduğuna dikkat edin.
sarnold

3
Not: Eğer dizeniz kullanıcı girdisi içeriyorsa, bu çok kötü bir fikirdir ve sizi kod enjeksiyon saldırılarına açık hale getirebilir.
Brian McCutchon

27

Tek tırnak içindeki değişkenler değerlendirilmez. Çift tırnak kullanın:

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

Kabuk, değişkenleri çift tırnak içinde genişletecek, ancak tek tırnak içinde genişletmeyecektir. Bu, sshkomuta geçmeden önce istediğiniz dizeye dönüşecektir .


3

(Bu yanıt gereksiz yere karmaşık görünebilir, ancak bildiğim kadarıyla beyaz boşluklar ve özel karakterler açısından kolayca genişletilebilir ve sağlamdır.)

Verileri doğrudan sshkomutun standart girişi aracılığıyla readve uzak konumdan besleyebilirsiniz .

Aşağıdaki örnekte,

  1. dizinlenmiş bir dizi, değerlerini uzak tarafta almak istediğiniz değişkenlerin adlarıyla doldurulur (kolaylık sağlamak için).
  2. Bu değişkenlerin her biri için, değişkenin sshadını ve değerini veren boş sonlu bir satır veriyoruz.
  3. Gelen shhkomutla kendisi, bu hatlar aracılığıyla döngü gerekli değişkenler için başlangıç için.
# 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"
'

Çıktı:

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

Bunlara ihtiyacınız yoksa export, declareyerine kullanabilmelisiniz export.

Bir gerçekten basitleştirilmiş versiyonu gibi görünecektir (eğer genişleme gerekmiyorsa, vb süreci için tek bir değişken var):

$ ssh user@somehost.com 'read foo' <<< "$foo"

2

Varsayılan olarak SSHD'de kabul edilen ortam değişkenlerinin listesi şunları içerir LC_*. Böylece:

LC_MY_BUILDN="1.2.3" ssh -o "SendEnv LC_MY_BUILDN" ssh-host 'echo $LC_MY_BUILDN'
1.2.3

1

Ortam değişkenlerini açıkça ssh aracılığıyla geçirmek de mümkündür. Bazı sunucu tarafı kurulumları gerektirir, bu yüzden bu evrensel bir cevap değildir.

Benim durumumda, yedekleme deposu şifreleme anahtarını yedek depolama sunucusundaki bir komuta, o anahtar orada saklanmadan geçirmek istedim, ancak herhangi bir ortam değişkeninin içinde göründüğüne dikkat edin ps! Anahtarı stdin'den geçirme çözümü de işe yarayacaktı, ancak bunu çok hantal buldum. Her durumda, bir ortam değişkenini ssh üzerinden şu şekilde geçirebilirsiniz:

Sunucuda, sshd_configgenellikle dosyayı düzenleyin ve iletmek istediğiniz değişkenlerle eşleşen /etc/ssh/sshd_configbir AcceptEnvyönerge ekleyin . Bakın man sshd_config. Benim durumumda, değişkenleri borg yedeklemesine geçirmek istiyorum, bu yüzden şunu seçtim:

AcceptEnv BORG_*

Şimdi, istemcide -o SendEnvortam değişkenlerini gönderme seçeneğini kullanın. Aşağıdaki komut satırı ortam değişkenini ayarlar BORG_SECRETve ardından istemci makineye (çağrılır backup) gönderilmek üzere işaretler . Daha sonra printenvorada çalışır ve BORG değişkenleri için çıktıyı filtreler:

$ BORG_SECRET=magic-happens ssh -o SendEnv=BORG_SECRET backup printenv | egrep BORG
BORG_SECRET=magic-happens

Varsayılan sunucu tarafı ayarlarını kullanarak değişkenlerinizi "kaçırabilirsiniz", cevabıma bakın . İşin özü, varsayılan OpenSSHd yapılandırmasının LC_*Değişkenlerin gönderilmesine izin verildiği şekilde içermesidir , bu nedenle yalnızca kullanın $LC_TvE_fooveya $LC_BORG_SECRETyerleşik bir değişkenle "çarpışmadığınızdan" emin olun.
Alex Stragies

0

Daha önce yanıtlandığı gibi, uzak ana bilgisayarda ortam değişkenini ayarlamanıza gerek yoktur. Bunun yerine, meta genişletmeyi yerel ana bilgisayarda yapabilir ve değeri uzak ana bilgisayara iletebilirsiniz.

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

Ortam değişkenini gerçekten uzak ana bilgisayarda ayarlamak ve kullanmak istiyorsanız, envprogramı kullanabilirsiniz.

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

Bu durumda bu biraz abartılıdır ve not

  • env BUILD_NUMBER=$BUILD_NUMBER meta genişleme yerel ana bilgisayarda mı
  • uzak BUILD_NUMBERortam değişkeni
    uzaktaki kabuk tarafından kullanılacak

-2

Ssh oturumu dışındaki değişkenlere erişmek için değişkenden kaçın: ssh pvt@192.168.1.133 "~ / tools / myScript.pl \ $ BUILD_NUMBER"


2
Bu, sorunun ne istediğini sağlamaz.
Patrick Trentin

2
kabuk açısından '$FOO'eşdeğerdir "\$FOO". soru "SSH ile bir kabuk değişkeni nasıl iletilir?" @PatrickTrentin tarafından daha önce belirtildiği gibi bu doğru bir cevap değildir çünkü bu durumda BUILD_NUMBERortam değişkeni uzaktan ayarlanmamıştır.
Gilles Gouaillardet
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.