Truyền các biến (biến môi trường) ssh
là có thể nhưng thường bị hạn chế.
Bạn cần nói với khách hàng để gửi cho họ. Ví dụ với OpenSSH, đó là:
ssh -o SendEnv=parameter host cmd...
Nhưng bạn cũng cần máy chủ chấp nhận nó ( AcceptEnv
chỉ thị cấu hình với OpenSSH). Chấp nhận bất kỳ biến nào là một rủi ro bảo mật lớn, do đó thường không được thực hiện theo mặc định, mặc dù một số triển khai ssh cho phép một số biến trong một số không gian tên (như LC_*
trong một số triển khai OpenSSH).
Bạn cũng cần xuất biến trước khi gọi ssh
, như:
LC_parameter="$parameter" ssh -o SendEnv=LC_parameter host csh << 'END'
echo $LC_parameter:q
END
Ở trên, chúng ta chuyển nội dung của $parameter
bash
biến shell thành biến LC_parameter
môi trường ssh
. ssh
gửi nó tới sshd
, nếu nó chấp nhận nó, chuyển nó dưới dạng biến môi trường tới shell đăng nhập của người dùng, sau đó chuyển nó tới csh
lệnh đó (sau đó có thể mở rộng nó).
Nhưng như đã đề cập trước đó, điều đó sẽ không hoạt động trừ khi quản trị viên của host
máy đã thêm một AcceptEnv LC_parameter
hoặc AcceptEnv LC_*
(điều đó đôi khi được thực hiện theo mặc định) vào sshd
cấu hình.
Thông Undefined variable
báo lỗi trong ví dụ của bạn cho thấy vỏ đăng nhập của người dùng từ xa là csh
hoặc tcsh
. Tốt hơn hết là gọi vỏ một cách rõ ràng để tránh những điều bất ngờ ( ssh host csh
cũng có nghĩa là một tty không được yêu cầu nên bạn không cần -T
). Lưu ý $LC_parameter:q
cú pháp, đó là csh
cách để truyền nội dung của một nguyên văn biến, không "$LC_parameter"
phải là không hoạt động nếu biến chứa các ký tự dòng mới.
Nếu sử dụng LC_*
biến không phải là một tùy chọn, thì thay vào đó, bạn có thể có trình vỏ máy khách ( bash
trong trường hợp của bạn) mở rộng biến. Một cách ngây thơ sẽ là với
ssh host csh << END
echo "$variable"
END
Nhưng điều đó sẽ nguy hiểm vì nội dung của biến sẽ được giải thích bởi shell từ xa. Nếu $variable
có chứa `reboot`
hoặc "; reboot; : "
ví dụ, điều đó sẽ có hậu quả xấu.
Vì vậy, trước tiên bạn cần đảm bảo biến được trích dẫn chính xác theo cú pháp của shell từ xa. Ở đây, tôi sẽ tránh csh
nơi khó thực hiện và sử dụng sh
/ bash
/ ksh
thay vào đó.
Sử dụng chức năng trợ giúp để thực hiện trích dẫn sh:
shquote() {
awk -v q=\' -v b='\\' '
BEGIN{
for (i=1; i<ARGC; i++) {
gsub(q, q b q q, ARGV[i])
printf "%s ", q ARGV[i] q
}
print ""
exit
}' "$@"
}
Và gọi ssh
là:
ssh host sh << END
parameter=$(shquote "$parameter")
echo "\$parameter"
END
Xem cách chúng ta thoát khỏi cái thứ ba $
để việc mở rộng $parameter
được thực hiện bởi shell từ xa chứ không phải cái cục bộ.