เริ่ม zsh ด้วย zshrc ที่กำหนดเอง


17

ฉันต้องการเริ่ม zsh ด้วยไฟล์ rc แบบกำหนดเองที่คล้ายกับคำสั่ง: bash --rc-file /path/to/file

หากไม่สามารถทำเช่นนั้นจะสามารถเริ่ม zsh, run source /path/to/fileแล้วยังคงอยู่ในเซสชัน zsh เดียวกันได้หรือไม่

หมายเหตุ: คำสั่งzsh --rcs /path/to/fileไม่ทำงานอย่างน้อยก็ไม่ใช่สำหรับฉัน ...

แก้ไข: ครบถ้วนฉันต้องการจะทำสิ่งต่อไปนี้: sshไปยังเซิร์ฟเวอร์ระยะไกล "example.com", รันzsh, sourceการกำหนดค่าของฉันอยู่ที่/path/to/file, ทั้งหมดใน 1 คำสั่ง นี่คือที่ฉันพยายามโดยเฉพาะอย่างยิ่งเพราะฉันไม่อยากเขียนไฟล์การกำหนดค่าใด ๆ บนเครื่องระยะไกล


1
สวัสดี Katz ยินดีต้อนรับสู่ unix.SE. ฉันได้แก้ไขคำถามของคุณเพื่อเพิ่มการจัดรูปแบบที่ทำให้อ่านง่ายขึ้น (เล็กน้อย) คุณสามารถคลิก "แก้ไข" เพื่อดูว่ามันทำงานอย่างไร ฉันได้ลบสิ่งพิเศษบางอย่างเช่น "ขอบคุณ" และลายเซ็นของคุณ (โพสต์ทั้งหมดในเครือข่ายสแต็คแลกเปลี่ยนมีการลงชื่อโดยอัตโนมัติ)
drs

1
ขอบคุณฉันได้เรียนรู้วิธีการพิมพ์code as such!
hjkatz

คำตอบ:


18

จากหน้าคน:

STARTUP/SHUTDOWN FILES
       Commands are first read from /etc/zshenv; this cannot be overridden.  Subsequent  be‐
       haviour is modified by the RCS and GLOBAL_RCS options; the former affects all startup
       files, while the second only affects global startup files (those shown here  with  an
       path starting with a /).  If one of the options is unset at any point, any subsequent
       startup file(s) of the corresponding type will not be read.  It is also possible  for
       a  file  in  $ZDOTDIR  to  re-enable  GLOBAL_RCS.  Both RCS and GLOBAL_RCS are set by
       default.

       Commands are then read from $ZDOTDIR/.zshenv.  If the shell is a  login  shell,  com‐
       mands are read from /etc/zprofile and then $ZDOTDIR/.zprofile.  Then, if the shell is
       interactive, commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc.  Finally, if
       the shell is a login shell, /etc/zlogin and $ZDOTDIR/.zlogin are read.

       When a login shell exits, the files $ZDOTDIR/.zlogout and then /etc/zlogout are read.
       This happens with either an explicit exit via the exit  or  logout  commands,  or  an
       implicit exit by reading end-of-file from the terminal.  However, if the shell termi‐
       nates due to exec'ing another process, the logout files are not read.  These are also
       affected  by  the  RCS and GLOBAL_RCS options.  Note also that the RCS option affects
       the saving of history files, i.e. if RCS is unset when the shell  exits,  no  history
       file will be saved.

       If  ZDOTDIR  is unset, HOME is used instead.  Files listed above as being in /etc may
       be in another directory, depending on the installation.

       As /etc/zshenv is run for all instances of zsh, it is important that it  be  kept  as
       small  as  possible.  In particular, it is a good idea to put code that does not need
       to be run for every single shell behind a test of the form `if [[  -o  rcs  ]];  then
       ...' so that it will not be executed when zsh is invoked with the `-f' option.

ดังนั้นคุณควรจะสามารถตั้งค่าตัวแปรสภาพแวดล้อมZDOTDIRเป็นไดเรกทอรีใหม่เพื่อรับ zsh เพื่อค้นหาชุด dotfiles ที่แตกต่างกัน

ในฐานะที่เป็นหน้าคนแนะนำRCSและGLOBAL_RCSไม่ได้เป็นเส้นทางไปยังไฟล์ rc ในขณะที่คุณพยายามที่จะใช้พวกเขา แต่ตัวเลือกที่คุณสามารถเปิดใช้งานหรือปิดการใช้งาน ตัวอย่างเช่นการตั้งค่าสถานะ--rcsจะเปิดใช้งานRCSตัวเลือกทำให้ zsh อ่านจากไฟล์ rc คุณสามารถใช้แฟล็กบรรทัดคำสั่งต่อไปนี้เพื่อ zsh เพื่อเปิดใช้งานRCSหรือปิดใช้งานหรือGLOBAL_RCS:

  --globalrcs
  --rcs
  -d    equivalent to --no-globalrcs
  -f    equivalent to --no-rcs

หากต้องการตอบคำถามอื่นของคุณ:

เป็นไปได้หรือไม่ที่จะเริ่ม zsh, เรียกใช้ "source / path / to / file", จากนั้นอยู่ในช่วง zsh เดียวกัน?

ใช่มันค่อนข้างง่ายตามคำแนะนำด้านบน เพียงแค่เรียกใช้แล้วzsh -d -fsource /path/to/zshrc


เช่นนี้ทำงานได้ตามคำถามของฉันฉันไม่ได้พูดถึงว่าฉันสามารถเรียกใช้ 1 คำสั่งเท่านั้น สิ่งนี้ไม่เป็นไปตามที่ฉันต้องการใช้สำหรับ (ssh แบบกำหนดเองพร้อมการกำหนดค่าส่วนบุคคลของฉัน) ปัญหาอยู่ในการทำงานที่zsh -d -f; source /path/to/fileไม่เคยรันคำสั่งที่สองในเซสชั่นแรกของ zsh จนกว่าจะออก
hjkatz

ฉันต้องการที่จะทำสิ่งต่อไปนี้อย่างครบถ้วน sshไปยังเซิร์ฟเวอร์ระยะไกล "example.com", รันzsh, sourceการกำหนดค่าของฉันอยู่ที่/path/to/file, ทั้งหมดใน 1 คำสั่ง นี่คือที่ฉันพยายามโดยเฉพาะอย่างยิ่งเพราะฉันไม่อยากเขียนไฟล์การกำหนดค่าใด ๆ บนเครื่องระยะไกล ขอบคุณสำหรับคำตอบ!
hjkatz

ดูเหมือนว่าปัญหาของคุณไม่ได้ใช้ zshrc ที่กำหนดเอง แต่ไม่รู้ว่าจะใช้เชลล์ผ่าน ssh ได้อย่างไร หากคุณรันssh host "zsh -d -f; source /path/to/file"ดังนั้น ssh จะรันครั้งแรกzshบนรีโมตโฮสต์จากนั้นsource ...หลังจากเชลล์ zsh จบการทำงาน แต่สิ่งที่คุณต้องการจะทำคือการที่จะลดลงในเปลือกโต้ตอบในพื้นที่ห่างไกลหรือถ้าคุณไม่ต้องการเปลือกโต้ตอบทำssh -t host zsh -d -f ssh host zsh -d -f -c \"source /path/to/file\; other command\; ... \"
jayhendren

ไม่ฉันเข้าใจว่า ssh ทำงานกับเชลล์แบบโต้ตอบได้อย่างไร ปัญหาคือการทำให้ssh -t host "zsh -d -f; source /path/to/fileฉันตกอยู่ในzshเชลล์แบบโต้ตอบ (และเป็นหมัน)
hjkatz

1
ฉันบอกคุณแล้วว่าทำไมถึงเป็นแบบนี้และวิธีแก้ไข เมื่อคุณรันssh -t host "zsh -d -f; source /path/to/file"คำสั่งsource...จะไม่ทำงานภายในเชลล์ zsh มันทำงานในเปลือกเข้าสู่ระบบของคุณหลังจากที่เปลือก zsh ออก ssh host "zsh; echo foo"การทดสอบนี้วิ่ง คุณจะเห็นผลลัพธ์ "foo" หลังจากคุณออกจากเปลือก zsh
jayhendren

4

ในขณะที่ใช้ ZDOTDIR คุณสามารถบอกzshให้ตีความไฟล์ที่เรียก.zshrcในไดเรกทอรีใด ๆ ที่คุณเลือกโดยที่มันแปลไฟล์ไฟล์ที่คุณเลือก (ไม่จำเป็นต้องเรียกว่า.zshrc) พิสูจน์ได้ยาก

ในshหรือการkshจำลองzshประเมิน$ENV; ดังนั้นคุณสามารถเพิ่มemulate zshที่ด้านบนของคุณ/path/to/fileและทำ:

ssh -t host 'zsh -c "ARGV0=sh ENV=/path/to/file exec zsh"'

อีกวิธีที่ซับซ้อนมากอาจเป็น:

ssh -t host 'PS1='\''${${functions[zsh_directory_name]::="
    set +o promptsubst
    unset -f zsh_directory_name
    unset PS1
    . /path/to/file
 "}+}${(D):-}${PS1=%m%# }'\' exec zsh -o promptsubst -f

คนนั้นสมควรได้รับคำอธิบายเล็กน้อย

${foo::=value}คือการขยายตัวของตัวแปรที่จริงชุด เป็นอาร์เรย์เชื่อมโยงพิเศษที่จับคู่ชื่อฟังก์ชันกับคำจำกัดความ$foo$functions

ด้วยpromptsubstตัวเลือกตัวแปรใน$PS1จะถูกขยาย ดังนั้นเมื่อพร้อมต์แรกตัวแปรใน PS1 นั้นจะถูกขยาย

zsh_directory_nameฟังก์ชั่นฟังก์ชั่นพิเศษที่จะช่วยให้การขยาย~fooไป/path/to/somethingและกลับ ที่ใช้สำหรับอินสแตนซ์ที่มี%~ในที่พรอมต์ที่ถ้าไดเรกทอรีปัจจุบันคือ/opt/myproj/proj/xคุณสามารถแสดงเป็น~proj:xโดยมีการzsh_directory_nameทำแมป<=>proj:x /opt/myproj/proj/xนอกจากนี้ยังใช้โดยการตั้งDค่าสถานะการขยายพารามิเตอร์ ดังนั้นหากการขยายตัว${(D)somevar}ที่zsh_directory_nameฟังก์ชั่นจะถูกเรียกว่า

นี่เรากำลังใช้${(D):-}, ${:-}นั่นคือ${no_var:-nothing}ขยายไปnothingถ้า$no_varว่างเปล่าดังนั้นจึงขยายไปไม่มีอะไรในขณะที่โทร${(D):-} ก่อนหน้านี้ได้ถูกกำหนดเป็น:zsh_directory_namezsh_directory_name

zsh_directory_name() {
  set +o promptsubst
  unset -f zsh_directory_name
  unset PS1; . /path/to/file
}

นั่นคือตามการขยาย PS1 แรก (ตามพรอมต์แรก) ${(D):-}จะทำให้promptsubstตัวเลือกไม่มีการตั้งค่า (เพื่อยกเลิกการ-o promptsubst) zsh_directory_name()จะไม่ได้กำหนด (ตามที่เราต้องการเรียกใช้เพียงครั้งเดียวเท่านั้น) $PS1เพื่อยกเลิกการตั้งค่าและ/path/to/fileเป็นแหล่งที่มา

${PS1=%m%# }ขยายตัว (และกำหนด$PS1) ไป%m%#เว้นแต่ PS1 ถูกกำหนดไว้แล้ว (เช่นโดย/path/to/fileหลังunset) และเกิดขึ้นเป็นค่าเริ่มต้นของ%m%#PS1


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