เหตุใดการส่งออกตัวแปรใน ssh shell จึงพิมพ์รายการตัวแปรที่ส่งออก


17

พิจารณาสิ่งนี้:

$ ssh localhost bash -c 'export foo=bar'
terdon@localhost's password: 
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x HOME="/home/terdon"
declare -x LOGNAME="terdon"
declare -x MAIL="/var/spool/mail/terdon"
declare -x OLDPWD
declare -x PATH="/usr/bin:/bin:/usr/sbin:/sbin"
declare -x PWD="/home/terdon"
declare -x SHELL="/bin/bash"
declare -x SHLVL="2"
declare -x SSH_CLIENT="::1 55858 22"
declare -x SSH_CONNECTION="::1 55858 ::1 22"
declare -x USER="terdon"
declare -x XDG_RUNTIME_DIR="/run/user/1000"
declare -x XDG_SESSION_ID="c5"
declare -x _="/usr/bin/bash"

เหตุใดการส่งออกตัวแปรภายในbash -cเซสชันจึงเรียกใช้ผ่านผลลัพธ์ ssh ในรายการdeclare -xคำสั่งนั้น (รายการของตัวแปรที่ส่งออกในปัจจุบันเท่าที่ฉันจะบอกได้)

ใช้สิ่งเดียวกันโดยbash -cไม่ทำสิ่งนั้น:

$ ssh localhost  'export foo=bar'
terdon@localhost's password: 
$

และมันจะไม่เกิดขึ้นหากเราไม่export:

$ ssh localhost bash -c 'foo=bar'
terdon@localhost's password: 
$ 

ฉันทดสอบสิ่งนี้โดย sshing จากเครื่อง Ubuntu เครื่องหนึ่งไปยังเครื่องอื่น (ทั้งที่กำลังรันทุบตี 4.3.11) และบนเครื่อง Arch ให้ทำตามที่แสดงไว้ด้านบน (ทุบตีรุ่น 4.4.5)

เกิดอะไรขึ้นที่นี่? เหตุใดการส่งออกตัวแปรภายในการbash -cโทรจึงสร้างเอาต์พุตนี้


นี้ไม่ตอบคำถาม exportแต่ผลลัพธ์คือผลของการทำงาน Zsh ทำสิ่งเดียวกัน
สตีเฟ่น Kitt

@StephenKitt ใช่ฉันรู้ว่าexportฉันพยายามที่จะเข้าใจว่าเกิดอะไรขึ้น ฉันจะแก้ไขเพื่อชี้แจงว่าสิ่งนี้จะเกิดขึ้นเฉพาะเมื่อส่งออกเท่านั้น
terdon

อาตกลงฉันอ่าน "รายการของตัวแปรที่ส่งออกในปัจจุบันเท่าที่ฉันสามารถบอกได้" ตามความหมายที่คุณไม่ทราบว่าผลลัพธ์มาจากไหน
สตีเฟ่น Kitt

@StephenKitt ฉันหมายถึงฉันไม่แน่ใจว่านั่นคือทุกตัวแปรที่ส่งออกหรือชุดย่อยเฉพาะหรืออะไร Oh! คุณหมายความว่ามันเป็นผลลัพธ์ของการexportทำงานคนเดียว ที่ฉันไม่เข้าใจ
terdon

โปรดทราบว่าfoo=barไม่ปรากฏในรายการ
deltab

คำตอบ:


31

เมื่อคุณเรียกใช้คำสั่งผ่านsshมันจะทำงานโดยการโทรของคุณ$SHELLด้วยการ-cตั้งค่าสถานะ:

-c    If the -c option is present, then commands are read from 
      the first non-option argument command_string.  If there  are
      arguments  after the command_string, the first argument is 
      assigned to $0 and any remaining arguments are assigned to
      the positional parameters.  

ดังนั้นssh remote_host "bash -c foo"จะทำงานจริง:

/bin/your_shell -c 'bash -c foo'

ตอนนี้เนื่องจากคำสั่งที่คุณกำลังทำงาน ( export foo=bar) มีช่องว่างและไม่ได้รับการอ้างอิงอย่างถูกต้องเพื่อสร้างทั้งexportคำสั่งจะถูกใช้เป็นคำสั่งที่จะทำงานและส่วนที่เหลือจะได้รับการบันทึกไว้ในอาร์เรย์พารามิเตอร์ตำแหน่ง ซึ่งหมายความว่าexportมีการเรียกใช้และถูกส่งไปเป็นfoo=bar $0ผลลัพธ์สุดท้ายนั้นเหมือนกับการวิ่ง

/bin/your_shell -c 'bash -c export'

คำสั่งที่ถูกต้องจะเป็น:

ssh remote_host "bash -c 'export foo=bar'"

9

ssh ต่ออาร์กิวเมนต์เข้ากับช่องว่างและให้เชลล์ล็อกอินของผู้ใช้รีโมตตีความมันดังนั้นใน:

ssh localhost bash -c 'export foo=bar'

ssh กำลังขอให้เปลือกระยะไกลตีความ

bash -c export foo=bar

คำสั่ง (ผลถ้าพื้นที่ห่างไกลเป็น Unix เหมือนมันจะทำงานเปลือกระยะไกลด้วยthe-shell, -cและbash -c export foo=barเป็นข้อโต้แย้ง)

เปลือกหอยส่วนใหญ่จะตีความบรรทัดคำสั่งที่เป็นเรียกใช้bashคำสั่งกับbash, -c, exportและfoo=barเป็นข้อโต้แย้ง (ทำงานดังนั้นexportในขณะที่$0มีfoo=bar) ในขณะที่คุณจะต้องการให้ทำงานด้วยbash, -cและexport foo=barเป็นข้อโต้แย้ง

สำหรับสิ่งนั้นคุณจะต้องใช้บรรทัดคำสั่งเช่น:

ssh localhost "bash -c 'export foo=bar'"

(หรือ:

ssh localhost bash -c \'export foo=bar\'

สำหรับเรื่องนั้น) ดังนั้น:

bash -c 'export foo=bar'

บรรทัดคำสั่งจะถูกส่งผ่านไปยังเปลือกระยะไกล บรรทัดคำสั่งที่จะได้รับการตีความโดยเปลือกหอยมากที่สุดเช่นการเรียกใช้bashคำสั่งด้วยbash, -cและexport foo=barเป็นข้อโต้แย้ง สังเกตว่าการใช้

ssh localhost 'bash -c "export foo=bar"'

จะไม่ทำงานหากล็อกอินเชลล์ของผู้ใช้รีโมตเป็นrcหรือesตัวอย่างที่"ไม่มีตัวดำเนินการการอ้างถึงพิเศษ ราคาเดียวเป็นส่วนใหญ่ผู้ประกอบการอ้างแบบพกพา (แม้ว่าจะมีการเปลี่ยนแปลงบางอย่างเกี่ยวกับวิธีที่พวกเขาจะถูกตีความระหว่างเปลือกหอยดูวิธีการดำเนินการคำสั่งง่ายๆโดยพลการผ่าน SSH โดยไม่ทราบว่าเปลือกเข้าสู่ระบบของผู้ใช้ระยะไกล?สำหรับข้อมูลเพิ่มเติมเกี่ยวกับที่)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.