ตามคำตอบของ 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…