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 sshlệ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 bashvà 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 sshgọ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, để bashnhậ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 bashnộ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à sshlệnh, theo sau là một đối số user@serverđược truyền cho sshlệ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 sshlệnh, trong trường hợp này sẽ được hiểu sshlà 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
catlà 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 catsẽ đượ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
EOTchấ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 catlệnh gọi . catxuấ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 sshdưới dạng một đối số dòng lệnh, sshsẽ 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 readbậ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…