Theo câu trả lời của zanco , bạn không cung cấp lệnh từ xa ssh
, cho biết cách shell phân tích dòng lệnh. Để giải quyết vấn đề này, hãy thay đổi cú pháp của ssh
lệnh gọi lệnh của bạn để lệnh từ xa bao gồm một chuỗi nhiều dòng chính xác về mặt cú pháp.
Có một loạt các cú pháp có thể được sử dụng. Ví dụ, vì các lệnh có thể được dẫn vào bash
và sh
, và có lẽ các shell khác cũng vậy, giải pháp đơn giản nhất là chỉ kết hợp lệnh ssh
gọi shell với heredocs:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Lưu ý rằng thực hiện các điều trên mà không có /bin/bash
kết quả cảnh báo Pseudo-terminal will not be allocated because stdin is not a terminal
. Cũng lưu ý rằng EOT
được bao quanh bởi các dấu ngoặc đơn, để bash
nhận ra heredoc là nowdoc , tắt nội suy biến cục bộ để văn bản lệnh sẽ được chuyển như nguyên trạng ssh
.
Nếu bạn là một fan hâm mộ của đường ống, bạn có thể viết lại như trên:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Cùng cảnh báo về /bin/bash
áp dụng cho ở trên.
Một cách tiếp cận hợp lệ khác là truyền lệnh từ xa nhiều dòng dưới dạng một chuỗi, sử dụng nhiều lớp bash
nội suy biến đổi như sau:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
Giải pháp trên khắc phục vấn đề này theo cách sau:
ssh user@server
được phân tích cú pháp bởi bash và được hiểu là ssh
lệnh, theo sau là một đối số user@server
được truyền cho ssh
lệnh
"
bắt đầu một chuỗi nội suy, khi hoàn thành, sẽ bao gồm một đối số được truyền cho ssh
lệnh, trong trường hợp này sẽ được hiểu ssh
là lệnh từ xa để thực thi như làuser@server
$(
bắt đầu một lệnh được thực thi, với đầu ra được bắt bởi chuỗi nội suy xung quanh
cat
là một lệnh để xuất nội dung của bất kỳ tập tin nào sau đây. Đầu ra của cat
sẽ được chuyển trở lại vào chuỗi nội suy bắt giữ
<<
bắt đầu một bash heredoc
'EOT'
xác định rằng tên của di truyền là EOT. Các trích dẫn đơn '
xung quanh EOT chỉ định rằng heredoc nên được phân tích cú pháp dưới dạng nowdoc , đây là một dạng đặc biệt của heredoc trong đó các nội dung không bị nội suy bởi bash, mà được truyền theo định dạng bằng chữ
Bất kỳ nội dung nào gặp phải giữa <<'EOT'
và <newline>EOT<newline>
sẽ được thêm vào đầu ra nowdoc
EOT
chấm dứt nowdoc, dẫn đến một tập tin tạm thời nowdoc được tạo và chuyển trở lại cat
lệnh gọi . cat
xuất ra nowdoc và chuyển đầu ra trở lại chuỗi nội suy bắt giữ
)
kết luận lệnh sẽ được thực thi
"
kết luận chuỗi nội suy bắt giữ. Nội dung của chuỗi nội suy sẽ được chuyển trở lại ssh
dưới dạng một đối số dòng lệnh, ssh
sẽ hiểu là lệnh từ xa để thực thi nhưuser@server
Nếu bạn cần tránh sử dụng các công cụ bên ngoài như cat
, và đừng read
bận tâm đến việc có hai câu lệnh thay vì một câu lệnh, hãy sử dụng tích hợp sẵn với một di sản để tạo lệnh SSH:
IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ssh user@server "${SSH_COMMAND}"
ssh user@server /bin/bash <<EOT…