sh ไฟล์เริ่มต้นผ่าน ssh


10

ฉันมีคำสั่งที่สำคัญบางอย่างที่ฉันต้องเรียกใช้ก่อนที่เชลล์ sh จะเริ่มทำงาน สิ่งนี้จำเป็นสำหรับการส่งคำสั่ง SSH ในคำสั่ง SSH ( ssh host somecommand) และโปรแกรมอื่น ๆ ที่เรียกใช้คำสั่ง

ในฉัน.profileฉันมีสิ่งนี้:

ihammerhands@wreckcreations:~> cat .profile
#specific environment and startup programs
export PS1="\u@wreckcreations:\w> "
export PYTHONPATH=~/python/lib/python2.4/site-packages
export PATH=$PATH:~/bin:~/python/bin

อย่างไรก็ตามสิ่งนี้ล้มเหลว:

W:\programming\wreckcreations-site\test-hg>ssh name@host echo $PATH
Enter passphrase for key '/home/Owner/.ssh/id_rsa':
/usr/local/bin:/bin:/usr/bin

สังเกตเห็นตัวเลือก PATH ที่หายไป

ชื่อที่เหมาะสมสำหรับโปรไฟล์ sh คืออะไร? หมายเหตุ: ฉันไม่สามารถเข้าถึงรูทและไม่ต้องการให้สิ่งนี้ใช้กับผู้ใช้รายอื่น มีวิธีอื่นในการทำเช่นนี้หรือไม่?


แก้ไข: ดูเหมือน/bin/shลิงค์ไปbashซึ่งไม่น่าแปลกใจ สิ่งที่น่าแปลกใจก็คือโปรไฟล์ของฉันยังคงเพิกเฉย ข้อเสนอแนะใด ๆ


1
ฉันไม่รู้สึกอยากทำซ้ำสิ่งที่อยู่ใน man page ดังนั้นเพียงแค่ดูใน bash man page ภายใต้หัวข้อ 'INVOCATION' ใกล้ด้านบนแล้วอธิบายทุกอย่างที่คุณจำเป็นต้องรู้
camh

ssh name@host -t echo $PATHคุณอาจจะลองใช้
Gert

@Gert เอาต์พุตเหมือนกัน
TheLQ

@camh คุณคิดว่าฉันจะถามคำถามนี้ถ้าฉันไม่ได้ตรวจสอบหน้าคน? ฉันได้อ่านพวกเขาหลายครั้ง + โพสต์อื่น ๆ แต่ไม่สามารถหาคำตอบสำหรับปัญหาเฉพาะนี้ได้เนื่องจากฉันไม่แน่ใจว่าคำสั่ง stage ssh และคำสั่งของโปรแกรมอื่นดำเนินการอย่างไร
TheLQ

1
@TheLQ: ฉันไม่รู้จักคุณดังนั้นฉันไม่รู้ว่าคุณจะตรวจสอบ man page หรือไม่ ทั้งหมดที่ฉันรู้ก็คือคำตอบอยู่ตรงนั้นดังนั้นแทนที่จะทำซ้ำคำต่อคำฉันจึงชี้ให้คุณเห็น ตัวชี้ที่เฉพาะเจาะจงมากขึ้นคือการค้นหาเชลล์ที่ไม่มีการโต้ตอบเนื่องจากนั่นคือสิ่งที่คุณต้องการใช้ หากสิ่งที่อยู่ในหน้าคนไม่ชัดเจนบางทีคุณอาจถามคำถามที่เฉพาะเจาะจงมากขึ้น
camh

คำตอบ:


8

ดูเหมือนว่าน่าสังเกตว่าคำสั่งที่คุณพูดถึงในคำถามของคุณ

ssh name@host echo $PATH

จะไม่มีประโยชน์อะไรเลย การทดแทนตัวแปรสำหรับ $ PATH ทำโดยเชลล์โลคัลของคุณและส่งผ่านไปยัง ssh ซึ่งดำเนินการ echo บนระบบรีโมตเพื่อพิมพ์เนื้อหาของตัวแปรพา ธ ขณะที่ขยายบนระบบโลคัลของคุณ นี่คือตัวอย่างของฉันที่ทำสิ่งที่คล้ายกันระหว่าง Mac และเครื่อง Linux บนเครือข่ายของฉัน:

LibMBP:~ will$ echo $PATH
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren echo $PATH
will@warren's password: 
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren 'echo $PATH'
will@warren's password: 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
LibMBP:~ will$ 

สังเกตว่าฉันต้องการใช้เครื่องหมายคำพูดเพื่อป้องกันเชลล์ในเครื่องของฉันจากการขยายตัวแปร


ใน Windows Cygwin land เครื่องหมายคำพูดเดี่ยวไม่ทำอะไรเลยใน Cygwin หรือ Command prompt น่าแปลกที่เครื่องหมายคำพูดคู่ทำให้ PATH ขยายอย่างสมบูรณ์ไปยังเครื่องท้องถิ่นของฉันใน Cygwin ดังนั้นอะไรก็ตามที่ ssh ให้ฉันไม่ใช่เส้นทางของฉันมันคือเซิร์ฟเวอร์
TheLQ

@TheLQ คุณจำเป็นต้องใช้อัญประกาศเดี่ยวที่พร้อมต์ unix (รวมถึง Cygwin) แต่คุณไม่จำเป็นต้องมีเครื่องหมายอัญประกาศที่ cmd prompt
Gilles 'หยุดความชั่วร้าย'

12

~/.profileดำเนินการโดยเชลล์ล็อกอินเท่านั้น โปรแกรมที่เรียกใช้เชลล์ตัดสินใจว่าเชลล์จะเป็นเชลล์ล็อกอินหรือไม่ (โดยการใส่-อักขระตัวแรกของอาร์กิวเมนต์ zeroth บนการเรียกใช้เชลล์) โดยทั่วไปจะไม่ดำเนินการเมื่อคุณเข้าสู่ระบบเพื่อดำเนินการคำสั่งเฉพาะ

โดยเฉพาะอย่างยิ่ง OpenSSH จะเรียกใช้ล็อกอินเชลล์เฉพาะในกรณีที่คุณไม่ได้ระบุคำสั่ง ดังนั้นหากคุณระบุคำสั่ง~/.profileจะไม่สามารถอ่านได้

OpenSSH อนุญาตให้ตั้งค่าตัวแปรสภาพแวดล้อมทางฝั่งเซิร์ฟเวอร์ สิ่งนี้จะต้องเปิดใช้งานในการกำหนดค่าเซิร์ฟเวอร์ด้วยPermitUserEnvironmentคำสั่ง ~/.ssh/environmentตัวแปรที่สามารถตั้งค่าในแฟ้ม สมมติว่าคุณใช้การรับรองความถูกต้องของกุญแจสาธารณะคุณยังสามารถตั้งค่าตัวแปรต่อคีย์ใน~/.ssh/authorized_keys: เพิ่มenvironment="FOO=bar"ที่จุดเริ่มต้นของบรรทัดที่เกี่ยวข้อง

Ssh ยังสนับสนุนการส่งตัวแปรสภาพแวดล้อม ใน OpenSSH ใช้คำสั่งในSendEnv ~/.ssh/configอย่างไรก็ตามตัวแปรสภาพแวดล้อมที่เฉพาะเจาะจงจะต้องเปิดใช้งานด้วยAcceptEnvคำสั่งในการกำหนดค่าเซิร์ฟเวอร์ดังนั้นสิ่งนี้อาจไม่ได้ผลสำหรับคุณ

สิ่งหนึ่งที่ผมคิดว่าก็ทำงาน (ผิดปกติพอ) ตราบใดที่คุณกำลังใช้ตรวจสอบคีย์สาธารณะคือการ(AB) ใช้command=ตัวเลือกในauthorized_keysไฟล์ รหัสที่มีcommandตัวเลือกนั้นดีสำหรับการเรียกใช้คำสั่งที่ระบุเท่านั้น แต่คำสั่งในauthorized_keysไฟล์จะทำงานโดยมีตัวแปรสภาพแวดล้อมSSH_ORIGINAL_COMMANDตั้งเป็นคำสั่งที่ผู้ใช้ระบุ ตัวแปรนี้ว่างเปล่าหากผู้ใช้ไม่ได้ระบุคำสั่งและคาดว่าจะมีเชลล์แบบโต้ตอบ ดังนั้นคุณสามารถใช้สิ่งนี้ใน~/.ssh/authorized_keys(แน่นอนมันจะไม่ใช้ถ้าคุณไม่ใช้คีย์นี้เพื่อตรวจสอบ):

command=". ~/.profile; if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then eval \"$SSH_ORIGINAL_COMMAND\"; else exec \"$SHELL\"; fi" ssh-rsa 

ความเป็นไปได้อีกอย่างหนึ่งคือการเขียนสคริปต์ตัวตัดคำบนเซิร์ฟเวอร์ สิ่งต่อไปนี้ใน~/bin/ssh-wrapper:

#!/bin/sh
. ~/.profile
exec "${0##*/}" "$@"

จากนั้นให้เชื่อมโยงสัญลักษณ์เพื่อสคริปต์นี้เรียกว่าrsync, unisonฯลฯ ผ่าน--rsync-path='bin/rsync'บนrsyncบรรทัดคำสั่งและอื่น ๆ สำหรับโปรแกรมอื่น ๆ อีกวิธีหนึ่งคือบางคำสั่งอนุญาตให้คุณระบุข้อมูลโค้ดเปลือกทั้งเพื่อให้ทำงานจากระยะไกลซึ่งจะช่วยให้คุณที่จะทำให้คำสั่งในตัวเอง: เช่นกับ rsync --rsync-path='. ~/.profile; rsync'คุณสามารถใช้

มีอเวนิวอีกทางหนึ่งซึ่งขึ้นอยู่กับเชลล์ล็อกอินของคุณว่าเป็น bash หรือ zsh Bash จะอ่านทุก~/.bashrcครั้งเมื่อมีการเรียกใช้โดย rshd หรือ sshd แม้ว่าจะไม่ใช่การโต้ตอบ (แต่ไม่ใช่ถ้าเรียกว่าเป็นsh) zsh ~/.zshenvเสมออ่าน

## ~/.bashrc
if [[ $- != *i* ]]; then
  # Either .bashrc was sourced explicitly, or this is an rsh/ssh session.
  . ~/.profile
fi

## ~/.zshenv
if [[ $(ps -p $PPID -o comm=) = [rs]shd && $- != *l* ]]; then
  # Not a login shell, but this is an rsh/ssh session
  . ~/.profile
fi

สิ่งที่เกี่ยวกับคำสั่งที่คำสั่งอื่นดำเนินการ? ในกรณีนี้มันจะเป็นตะขอ Mercurial Mercurial ต้องอยู่บนเส้นทางที่จะขอให้นึกถึงการทำงานด้วย
TheLQ

ใช้เทคนิคใด ๆ ที่ฉันระบุเพื่อให้โปรไฟล์ของคุณทำงานในคำสั่ง ssh แบบไม่โต้ตอบ หนึ่งของพวกเขา ( command=ในauthorized_keys) ทำงานอย่างโปร่งใส อื่น ๆ ต้องการเชลล์หรือตัวเลือกเฉพาะในการกำหนดค่าเซิร์ฟเวอร์ ssh เทียบเท่า Mercurial ของมี--rsync-path --remotecmd
Gilles 'หยุดความชั่วร้าย'

มันอาจจะมีประโยชน์สำหรับบางคนที่จะรวมcommand=คำสั่งแบบเต็มเช่นเดียวกับในโพสต์ของคุณsuperuser.com/a/207262/137762
mforbes

1

โดยปกติเมื่อเข้าสู่ระบบ bash จะอ่านคำสั่งจาก:

~ / .bash_profile
~ / .bashrc

จากหน้าคนทุบตี:

~ / .bash_profile ไฟล์
การกำหนดค่าเริ่มต้นส่วนบุคคลซึ่งดำเนินการสำหรับล็อกอินเชลล์

~ / .bashrc ไฟล์
เริ่มต้นต่อเชลล์แบบโต้ตอบแต่ละไฟล์


0

ฉันหมดเวลาทดสอบ แต่ดูหน้าคนที่ฉันพบ:

man bash: เมื่อ bash เริ่มต้นแบบไม่โต้ตอบเพื่อรันเชลล์สคริปต์ตัวอย่างเช่นจะค้นหาตัวแปร BASH_ENV ในสภาพแวดล้อมขยายค่าถ้ามันปรากฏที่นั่นและใช้ค่าที่ขยายเป็นชื่อไฟล์ อ่านและดำเนินการ Bash จะทำงานเหมือนกับคำสั่งต่อไปนี้ถูกดำเนินการ: ถ้า [-n "$ BASH_ENV"]; จากนั้น "$ BASH_ENV"; fi แต่ค่าของตัวแปร PATH ไม่ได้ถูกใช้เพื่อค้นหาชื่อไฟล์

man ssh: ~ / .ssh / environment มีคำจำกัดความเพิ่มเติมสำหรับตัวแปรสภาพแวดล้อม ดูสภาพแวดล้อมด้านบน

การรวมกันแสดงให้เห็นว่าคุณสามารถให้ ssh รัน. profile ได้อย่างไร

น่าเสียดายที่เซิร์ฟเวอร์ของฉันมี PermitUserEnvironment เป็นค่าเริ่มต้นที่ไม่ใช่ซึ่งทำให้สิ่งนี้ไม่ได้ผลสำหรับฉัน (และอย่างที่ฉันบอกว่าฉันไม่มีเวลาเล่นอีกต่อไป)


แม้ว่าฉันจะสามารถให้ SSH ทำงานได้โดยการระบุตัวแปรสภาพแวดล้อมบางอย่างในสภาพแวดล้อมอย่างชัดเจน แต่ก็ยังไม่ช่วยแก้ไขโปรไฟล์ของฉันที่จะถูกเรียกใช้เมื่อโปรแกรมอื่นเรียกคำสั่ง
TheLQ

ในตัวอย่างของคุณสิ่งที่คุณทำคือการตั้งค่าตัวแปรสภาพแวดล้อมคุณต้องการทำอะไรอีก
kasterma

0

(ลบแล้ว ... สามารถมีการเชื่อมโยงหลายมิติได้ในฐานะผู้ใช้ใหม่ ~)

ปรับปรุง

ขออภัยฉันไม่เห็นว่านี่เป็นเรื่องเกี่ยวกับเซสชันที่ไม่มีการโต้ตอบซึ่งลิงก์ดังกล่าวใช้ไม่ได้

เมื่อ Bash เริ่มต้นในโหมดที่เข้ากันได้กับ SH มันจะพยายามเลียนแบบพฤติกรรมการเริ่มต้นของ sh เวอร์ชั่นที่ใกล้เคียงที่สุดเท่าที่จะเป็นไปได้ในขณะที่สอดคล้องกับมาตรฐานPOSIX®เช่นกัน ไฟล์โปรไฟล์ที่อ่านคือ / etc / profile และ ~ / .profile หากเป็นเชลล์ล็อกอิน

หากไม่ใช่เชลล์ล็อกอินตัวแปรสภาวะแวดล้อม ENV จะถูกประเมินและชื่อไฟล์ผลลัพธ์จะถูกใช้เป็นชื่อของไฟล์เริ่มต้น

หลังจากอ่านไฟล์เริ่มต้นแล้ว Bash จะเข้าสู่โหมดที่เข้ากันได้กับ POSIX (r) (สำหรับการทำงานไม่ใช่สำหรับการเริ่มต้น!)

Bash เริ่มต้นในโหมด sh compatiblity เมื่อ:

  • ชื่อไฟล์พื้นฐานใน argv [0] คือ sh (:!: โปรดทราบว่าผู้ใช้ Linux ที่ฉลาด uber-clever ... / bin / sh อาจเชื่อมโยงกับ / bin / bash แต่นั่นไม่ได้หมายความว่ามันทำหน้าที่เหมือน / bin / bash : :)

ดังนั้นคำถามคือทำไมมันไม่ทำงานแม้ว่าเปลือกของคุณจะเริ่มต้นเช่นนี้

แหล่ง


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