Truyền các biến trong lệnh ssh từ xa


99

Tôi muốn có thể chạy một lệnh từ máy của mình bằng ssh và chuyển qua biến môi trường $BUILD_NUMBER

Đây là những gì tôi đang thử:

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

$BUILD_NUMBER được đặt trên máy thực hiện cuộc gọi ssh và vì biến không tồn tại trên máy chủ từ xa nên nó không được chọn.

Làm cách nào để chuyển giá trị của $BUILD_NUMBER?


1
không liên quan đến Hudson, đã xóa thẻ. (Hudson chỉ tạo ra các biến)
Peter Schuetze

Câu trả lời:


188

Nếu bạn dùng

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

thay vì

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

shell của bạn sẽ nội suy $BUILD_NUMBERtrước khi gửi chuỗi lệnh đến máy chủ từ xa.


8
Nếu ai đó PHẢI sử dụng các dấu ngoặc kép để lệnh có trong dấu ngoặc kép không được đánh giá cục bộ, thì họ nên sử dụng "'$ VARIABLE'". Ví dụ: ssh pvt@192.168.1.133 '~ / tools / run_pvt.pl "' $ BUILD_NUMBER '"'
dr.doom

3
không biết rằng bash phản ứng khác nhau với dấu nháy đơn và dấu nháy kép. Cảm ơn!
silgon

1
các nhà phát triển cốt lõi Linux phải đốt cháy trong địa ngục
goldstar

@goldstar, lưu ý rằng sự khác biệt giữa hành vi trích dẫn đơn và báo giá kép trong shell có trước Linux hàng thập kỷ.
sarnold

3
PSA: nếu chuỗi của bạn chứa đầu vào của người dùng, đây là một ý tưởng rất tồi và có thể khiến bạn phải hứng chịu các cuộc tấn công chèn mã.
Brian McCutchon

27

Các biến trong dấu ngoặc đơn không được đánh giá. Sử dụng dấu ngoặc kép:

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

Trình bao sẽ mở rộng các biến trong dấu ngoặc kép, nhưng không mở rộng trong dấu ngoặc đơn. Điều này sẽ thay đổi thành chuỗi mong muốn của bạn trước khi được chuyển đến sshlệnh.


2

(Câu trả lời này có vẻ phức tạp không cần thiết, nhưng nó dễ dàng mở rộng và mạnh mẽ liên quan đến khoảng trắng và các ký tự đặc biệt, theo như tôi biết.)

Bạn có thể cung cấp dữ liệu ngay thông qua đầu vào chuẩn của sshlệnh và readtừ vị trí từ xa.

Trong ví dụ sau,

  1. một mảng được lập chỉ mục được điền (để thuận tiện) với tên của các biến có giá trị mà bạn muốn truy xuất ở phía từ xa.
  2. Đối với mỗi biến đó, chúng tôi cung cấp cho sshmột dòng kết thúc bằng null cho biết tên và giá trị của biến.
  3. Trong shhchính lệnh, chúng ta lặp qua các dòng này để khởi tạo các biến cần thiết.
# 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"
'

Đầu ra:

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

Nếu bạn không cần đến exportnhững thứ đó, bạn có thể sử dụng declarethay thế export.

Một phiên bản thực sự đơn giản (nếu bạn không cần khả năng mở rộng, có một biến duy nhất để xử lý, v.v.) sẽ giống như sau:

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

2

Danh sách các biến môi trường được chấp nhận trên SSHD theo mặc định bao gồm LC_*. Như vậy:

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

0

Như đã trả lời trước đây, bạn không cần đặt biến môi trường trên máy chủ từ xa. Thay vào đó, bạn có thể chỉ cần thực hiện mở rộng meta trên máy chủ cục bộ và chuyển giá trị cho máy chủ từ xa.

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

Nếu bạn thực sự muốn đặt biến môi trường trên máy chủ từ xa và sử dụng nó, bạn có thể sử dụng envchương trình

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

Trong trường hợp này, đây là một chút quá mức cần thiết, và lưu ý

  • env BUILD_NUMBER=$BUILD_NUMBER có mở rộng meta trên máy chủ cục bộ không
  • BUILD_NUMBERbiến môi trường từ xa sẽ được
    trình bao từ xa sử dụng

0

Cũng có thể chuyển các biến môi trường một cách rõ ràng qua ssh. Nó yêu cầu một số thiết lập phía máy chủ, vì vậy đây không phải là một câu trả lời phổ biến.

Trong trường hợp của tôi, tôi muốn chuyển khóa mã hóa kho lưu trữ sao lưu cho một lệnh trên máy chủ lưu trữ dự phòng mà không cần lưu trữ khóa đó ở đó, nhưng lưu ý rằng mọi biến môi trường đều hiển thị trong ps ! Giải pháp chuyển khóa trên stdin cũng sẽ hoạt động, nhưng tôi thấy nó quá cồng kềnh. Trong mọi trường hợp, đây là cách chuyển một biến môi trường qua ssh:

Trên máy chủ, hãy chỉnh sửa sshd_configtệp, thông thường /etc/ssh/sshd_configvà thêm một AcceptEnvchỉ thị phù hợp với các biến bạn muốn chuyển. Thấy chưa man sshd_config. Trong trường hợp của tôi, tôi muốn chuyển các biến vào bản sao lưu borg nên tôi đã chọn:

AcceptEnv BORG_*

Bây giờ, trên máy khách sử dụng -o SendEnvtùy chọn để gửi các biến môi trường. Dòng lệnh sau đặt biến môi trường BORG_SECRETvà sau đó gắn cờ biến nó sẽ được gửi đến máy khách (được gọi backup). Sau đó, nó chạy printenvở đó và lọc đầu ra cho các biến BORG:

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

Bạn có thể "nhập lậu" các biến của mình bằng cách sử dụng cài đặt phía máy chủ mặc định, hãy xem câu trả lời của tôi . Ý chính là, cấu hình OpenSSHd mặc định bao gồm các LC_*Biến được phép gửi, vì vậy chỉ cần sử dụng $LC_TvE_foohoặc $LC_BORG_SECRET, chỉ cần đảm bảo rằng bạn không "va chạm" với một biến tích hợp.
Alex Stragies

-2

Thoát biến để truy cập các biến bên ngoài phiên ssh: ssh pvt@192.168.1.133 "~ / tools / myScript.pl \ $ BUILD_NUMBER"


2
Điều này không đạt được những gì câu hỏi đang yêu cầu.
Patrick Trentin

2
từ một quan điểm của shell, '$FOO'tương đương với "\$FOO". câu hỏi là "làm thế nào để truyền một biến shell với SSH?". Như đã được nêu bởi @PatrickTrentin, đây không phải là một câu trả lời chính xác vì khi đó BUILD_NUMBERbiến môi trường không được đặt từ xa.
Gilles Gouaillardet
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.