Meneruskan variabel dalam perintah ssh jarak jauh

99

Saya ingin dapat menjalankan perintah dari mesin saya menggunakan ssh dan melewati variabel lingkungan $BUILD_NUMBER

Inilah yang saya coba:

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

$BUILD_NUMBER diatur pada mesin yang melakukan panggilan ssh dan karena variabel tidak ada pada host jarak jauh, variabel tidak diambil.

Bagaimana cara menyampaikan nilai $BUILD_NUMBER?

Fergal
sumber
1
tidak terkait dengan Hudson, menghapus tag tersebut. (Hudson baru saja membuat variabel)
Peter Schuetze

Jawaban:

189

Jika Anda menggunakan

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

dari pada

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

shell Anda akan menginterpolasi $BUILD_NUMBERsebelum mengirim string perintah ke host jarak jauh.

sarnold
sumber
8
Jika seseorang HARUS menggunakan tanda kutip tunggal sehingga perintah yang disertakan dalam tanda kutip tidak dievaluasi secara lokal, maka mereka harus menggunakan "'$ VARIABLE'". Contoh: ssh [email protected] '~ / tools / run_pvt.pl "' $ BUILD_NUMBER '"'
dr.doom
3
tidak tahu bahwa bash bereaksi berbeda dengan tanda kutip tunggal dan tanda kutip ganda. Terima kasih!
silgon
1
pengembang inti linux harus terbakar di neraka
goldstar
@goldstar, perhatikan bahwa perbedaan antara perilaku kutipan tunggal dan kutip ganda di shell sudah ada beberapa dekade sebelum Linux.
sarnold
3
PSA: jika string Anda berisi input pengguna, ini adalah ide yang sangat buruk, dan dapat membuat Anda terkena serangan injeksi kode.
Brian McCutchon
27

Variabel dalam tanda kutip tunggal tidak dievaluasi. Gunakan tanda kutip ganda:

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

Shell akan memperluas variabel dalam tanda kutip ganda, tetapi tidak dalam tanda kutip tunggal. Ini akan berubah menjadi string yang Anda inginkan sebelum diteruskan ke sshperintah.

Stephen
sumber
3

(Jawaban ini mungkin tampak tidak perlu rumit, tetapi mudah diperluas dan kuat terkait spasi putih dan karakter khusus, sejauh yang saya tahu.)

Anda dapat memasukkan data langsung melalui input standar sshperintah dan readdari lokasi jarak jauh.

Dalam contoh berikut,

  1. array yang diindeks diisi (untuk kenyamanan) dengan nama-nama variabel yang nilainya ingin Anda ambil di sisi jarak jauh.
  2. Untuk masing-masing variabel tersebut, kami berikan kepada ssh baris yang diakhiri dengan null yang memberikan nama dan nilai variabel.
  3. Dalam shhperintah itu sendiri, kami melakukan perulangan melalui baris-baris ini untuk menginisialisasi variabel yang diperlukan.
# 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"
'

Keluaran:

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

Jika Anda tidak perlu exportorang-orang, Anda harus dapat menggunakan declarebukan export.

Versi yang sangat sederhana (jika Anda tidak memerlukan ekstensibilitas, memiliki satu variabel untuk diproses, dll.) Akan terlihat seperti:

$ ssh user@somehost.com 'read foo' <<< "$foo"
Alice M.
sumber
2

Daftar variabel lingkungan yang diterima di SSHD secara default disertakan LC_*. Jadi:

LC_MY_BUILDN="1.2.3" ssh -o "SendEnv LC_MY_BUILDN" ssh-host 'echo $LC_MY_BUILDN'
1.2.3
Alex Stragies
sumber
0

Seperti yang telah dijawab sebelumnya, Anda tidak perlu menyetel variabel lingkungan pada host jarak jauh. Sebagai gantinya, Anda cukup melakukan perluasan meta pada host lokal, dan meneruskan nilainya ke host jarak jauh.

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

Jika Anda benar-benar ingin menyetel variabel lingkungan pada host jarak jauh dan menggunakannya, Anda dapat menggunakan env program ini

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

Dalam hal ini ini adalah sedikit berlebihan, dan perhatikan

  • env BUILD_NUMBER=$BUILD_NUMBER melakukan ekspansi meta pada host lokal
  • BUILD_NUMBERvariabel lingkungan jarak jauh akan digunakan oleh
    shell jarak jauh
Gilles Gouaillardet
sumber
0

Dimungkinkan juga untuk melewatkan variabel lingkungan secara eksplisit melalui ssh. Itu memang membutuhkan beberapa pengaturan sisi server, jadi ini bukan jawaban universal.

Dalam kasus saya, saya ingin meneruskan kunci enkripsi repositori cadangan ke perintah di server penyimpanan cadangan tanpa kunci itu disimpan di sana, tetapi perhatikan bahwa variabel lingkungan apa pun terlihat di ps ! Solusi meneruskan kunci pada stdin juga akan berfungsi, tetapi saya merasa itu terlalu rumit. Bagaimanapun, berikut ini cara meneruskan variabel lingkungan melalui ssh:

Di server, edit sshd_configfile, biasanya /etc/ssh/sshd_configdan tambahkan AcceptEnvperintah yang cocok dengan variabel yang ingin Anda teruskan. Lihat man sshd_config. Dalam kasus saya, saya ingin meneruskan variabel ke borg backup jadi saya memilih:

AcceptEnv BORG_*

Sekarang, pada klien gunakan -o SendEnvopsi untuk mengirim variabel lingkungan. Baris perintah berikut menetapkan variabel lingkungan BORG_SECRETdan kemudian menandainya untuk dikirim ke mesin klien (dipanggil backup). Ini kemudian berjalan di printenvsana dan memfilter output untuk variabel BORG:

$ BORG_SECRET=magic-happens ssh -o SendEnv=BORG_SECRET backup printenv | egrep BORG
BORG_SECRET=magic-happens
TvE
sumber
Anda dapat "menyelundupkan" variabel Anda menggunakan pengaturan sisi server default, lihat jawaban saya . Intinya adalah, konfigurasi OpenSSHd default tersebut menyertakan LC_*Variabel yang diizinkan untuk dikirim, jadi gunakan saja $LC_TvE_foo, atau $LC_BORG_SECRET, pastikan Anda tidak "bertabrakan" dengan variabel bawaan .
Alex Stragies
-2

Escape variabel untuk mengakses variabel di luar sesi ssh: ssh [email protected] "~ / tools / myScript.pl \ $ BUILD_NUMBER"

Sarah Gruneisen
sumber
2
Ini tidak mencapai apa yang diminta pertanyaan.
Patrick Trentin
2
dari sudut pandang shell, '$FOO'sama dengan "\$FOO". pertanyaannya adalah "bagaimana cara melewatkan variabel shell dengan SSH?". Seperti yang telah dinyatakan oleh @PatrickTrentin, ini bukan jawaban yang benar karena BUILD_NUMBERvariabel lingkungan tidak disetel dari jarak jauh.
Gilles Gouaillardet