ตามคำตอบของ zancoคุณไม่ได้ให้คำสั่งระยะไกลเพื่อsshให้เชลล์แจงคำสั่งบรรทัดคำสั่ง เมื่อต้องการแก้ไขปัญหานี้ให้เปลี่ยนไวยากรณ์ของsshการเรียกใช้คำสั่งของคุณเพื่อให้คำสั่งระยะไกลประกอบด้วยสตริงหลายบรรทัดที่ถูกต้องทางไวยากรณ์
มีไวยากรณ์ที่หลากหลายที่สามารถใช้ได้ ตัวอย่างเช่นเนื่องจากคำสั่งสามารถไพพ์ลงในbashและshและอาจเป็นเชลล์อื่นด้วยโซลูชันที่ง่ายที่สุดคือการรวมsshการเรียกใช้เชลล์กับ heredocs:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
โปรดทราบว่าการดำเนินการดังกล่าวข้างต้นโดยไม่ต้อง จะมีผลในการแจ้งเตือน/bin/bash Pseudo-terminal will not be allocated because stdin is not a terminalนอกจากนี้ยังทราบว่าEOTถูกล้อมรอบด้วยคำพูดเดียวเพื่อให้bashตระหนักถึงความ heredoc เป็นnowdocsshปิดการแก้ไขตัวแปรท้องถิ่นเพื่อให้ข้อความคำสั่งจะถูกส่งผ่านไปตามที่เป็นไป
หากคุณเป็นแฟนของท่อคุณสามารถเขียนข้างต้นดังต่อไปนี้:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ข้อแม้เดียวกันเกี่ยวกับ/bin/bashใช้กับข้างต้น
อีกวิธีที่ถูกต้องคือการส่งคำสั่งรีโมตหลายบรรทัดเป็นสตริงเดี่ยวโดยใช้การbashแก้ไขตัวแปรหลายเลเยอร์ดังนี้
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
การแก้ปัญหาข้างต้นแก้ไขปัญหานี้ในลักษณะดังต่อไปนี้:
ssh user@serverถูกแยกวิเคราะห์โดย bash และตีความว่าเป็นsshคำสั่งตามด้วยอาร์กิวเมนต์ที่user@serverจะถูกส่งผ่านไปยังsshคำสั่ง
"เริ่มต้นสตริง interpolated ซึ่งเมื่อเสร็จแล้วจะประกอบด้วยอาร์กิวเมนต์ที่จะส่งผ่านไปยังsshคำสั่งซึ่งในกรณีนี้จะถูกตีความโดยsshเป็นคำสั่งระยะไกลเพื่อดำเนินการตามuser@server
$( เริ่มต้นคำสั่งที่จะดำเนินการกับเอาท์พุทที่ถูกจับโดยสตริง interpolated โดยรอบ
catเป็นคำสั่งเพื่อส่งออกเนื้อหาของไฟล์ใดก็ตามที่ตามมา เอาต์พุตของcatจะถูกส่งกลับไปยังสตริงการแก้ไขที่จับภาพ
<<เริ่มheredocทุบตี
'EOT'ระบุว่าชื่อของ heredoc คือ EOT เครื่องหมายอัญประกาศเดี่ยว'ล้อมรอบ EOT ระบุว่า heredoc ควรได้รับการแจงเป็นnowdocซึ่งเป็นรูปแบบพิเศษของ heredoc ซึ่งเนื้อหาไม่ได้รับการสอดแทรกด้วย bash แต่ส่งผ่านในรูปแบบตัวอักษร
เนื้อหาใด ๆ ที่พบระหว่าง<<'EOT'และ<newline>EOT<newline>จะถูกผนวกเข้ากับเอาต์พุต nowdoc
EOTยุติ nowdoc ทำให้ไฟล์ nowdoc ชั่วคราวถูกสร้างขึ้นและส่งกลับไปยังcatคำสั่งการโทร catเอาต์พุต nowdoc และส่งผ่านเอาต์พุตกลับไปยังสตริงการแก้ไขที่จับภาพ
) สรุปคำสั่งที่จะดำเนินการ
"สรุปสตริงการแก้ไขที่จับภาพ เนื้อหาของสตริงการสอดแทรกจะถูกส่งกลับไปsshเป็นอาร์กิวเมนต์บรรทัดคำสั่งเดียวซึ่งsshจะตีความว่าเป็นคำสั่งระยะไกลเพื่อดำเนินการตามuser@server
หากคุณจำเป็นต้องหลีกเลี่ยงการใช้เครื่องมือภายนอกเช่นcatและไม่ต้องreadกังวลว่าจะมีสองข้อความสั่งแทนที่จะเป็นคำเดียวให้ใช้คำสั่งในตัวพร้อม heredoc เพื่อสร้างคำสั่ง 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…