Mulai zsh dengan zshrc khusus

17

Saya ingin dapat memulai zsh dengan file rc khusus yang mirip dengan perintah: bash --rc-file /path/to/file

Jika ini tidak mungkin, maka apakah mungkin untuk memulai zsh, jalankan source /path/to/file, lalu tetap di sesi zsh yang sama?

Catatan: Perintah zsh --rcs /path/to/filetidak berfungsi, setidaknya tidak untuk saya ...

EDIT: Secara keseluruhan saya ingin dapat melakukan hal berikut: sshke server jarak jauh "example.com", jalankan zsh, sourcekonfigurasi saya terletak di /path/to/file, semua dalam 1 perintah. Di sinilah saya berjuang, terutama karena saya lebih suka tidak menulis file konfigurasi pada mesin remote.

hjkatz
sumber
1
Hai Katz, selamat datang di unix.SE. Saya telah mengedit pertanyaan Anda untuk menambahkan beberapa format yang membuatnya (sedikit) lebih mudah dibaca. Anda dapat mengklik "edit" untuk melihat cara kerjanya. Saya juga telah menghapus beberapa hal tambahan, seperti "Terima kasih" dan tanda tangan Anda (semua posting di jaringan Stack Exchange ditandatangani secara otomatis).
drs
1
Terima kasih, saya sekarang sudah belajar mengetik code as such!
hjkatz

Jawaban:

18

Dari halaman manual:

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.

jadi Anda harus dapat mengatur variabel lingkungan ZDOTDIRke direktori baru untuk mendapatkan zsh untuk mencari kumpulan dotfile yang berbeda.

Seperti yang disarankan oleh halaman manual, RCSdan GLOBAL_RCSbukan path ke file rc, seperti yang Anda coba gunakan, melainkan opsi yang dapat Anda aktifkan atau nonaktifkan. Jadi, misalnya, flag --rcsakan mengaktifkan RCSopsi, menyebabkan zsh membaca dari file rc. Anda dapat menggunakan flag baris perintah berikut untuk zsh untuk mengaktifkan atau menonaktifkan RCSatau GLOBAL_RCS:

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

Untuk menjawab pertanyaan Anda yang lain:

apakah mungkin untuk memulai zsh, jalankan "source / path / to / file", kemudian tetap di sesi zsh yang sama?

Ya, ini cukup mudah sesuai dengan petunjuk di atas. Jalankan saja zsh -d -fdan kemudian source /path/to/zshrc.

jayhendren
sumber
Karena ini berfungsi sesuai pertanyaan saya, saya gagal menyebutkan bahwa saya hanya dapat menjalankan 1 perintah. Ini tidak memuaskan untuk apa saya ingin menggunakan ini (custom ssh dengan konfigurasi pribadi saya). Masalahnya terletak pada menjalankan yang zsh -d -f; source /path/to/filetidak pernah menjalankan perintah kedua di sesi pertama zsh sampai keluar.
hjkatz
Secara keseluruhan saya berharap dapat melakukan hal berikut. sshke server jarak jauh "example.com", jalankan zsh, sourcekonfigurasi saya terletak di /path/to/file, semua dalam 1 perintah. Di sinilah saya berjuang, terutama karena saya lebih suka tidak menulis file konfigurasi pada mesin remote. Terima kasih atas jawaban Anda!
hjkatz
Sepertinya masalah Anda bukan dalam menggunakan zshrc khusus tetapi tidak tahu cara menggunakan shell di atas ssh. Jika Anda menjalankan ssh host "zsh -d -f; source /path/to/file", maka ssh akan dijalankan pertama kali zshpada host jarak jauh, kemudian source ...setelah shell zsh keluar. Sebaliknya yang ingin Anda lakukan adalah ssh -t host zsh -d -fmemasukkan shell interaktif ke host jarak jauh, atau jika Anda tidak ingin shell interaktif, lakukan ssh host zsh -d -f -c \"source /path/to/file\; other command\; ... \".
jayhendren
Tidak, saya mengerti bagaimana ssh bekerja dengan shell interaktif. Masalahnya adalah bahwa menjalankan ssh -t host "zsh -d -f; source /path/to/filemenjatuhkan saya ke zshshell interaktif (dan tandus) .
hjkatz
1
Saya sudah memberi tahu Anda mengapa ini dan bagaimana cara memperbaikinya. Ketika Anda menjalankan ssh -t host "zsh -d -f; source /path/to/file", perintah source...TIDAK dijalankan di dalam zsh shell. Ini dijalankan di shell login Anda setelah shell zsh keluar. Untuk menguji ini, jalankan ssh host "zsh; echo foo". Anda akan melihat output "foo" setelah Anda keluar dari shell zsh.
jayhendren
4

sementara dengan ZDOTDIR, Anda dapat meminta zshuntuk menginterpretasikan file yang dipanggil .zshrcdi direktori mana pun yang Anda pilih, setelah itu menafsirkan file apa pun yang Anda pilih (tidak harus disebut .zshrc) terbukti cukup sulit.

Dalam shatau kshemulasi, zshevaluasi $ENV; sehingga Anda dapat menambahkan emulate zshdi bagian atas Anda /path/to/filedan lakukan:

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

Pendekatan lain yang sangat berbelit-belit adalah:

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

Yang itu layak mendapat sedikit penjelasan.

${foo::=value}adalah ekspansi variabel yang benar-benar ditetapkan $foo . $functionsadalah array asosiatif khusus yang memetakan nama fungsi ke definisi mereka.

Dengan promptsubstopsi, variabel dalam $PS1diperluas. Jadi, pada prompt pertama, variabel dalam PS1 akan diperluas.

The zsh_directory_namefungsi fungsi khusus yang membantu memperluas ~fooke /path/to/somethingdan sebaliknya. Itu digunakan misalnya dengan %~di prompt sehingga jika direktori saat ini /opt/myproj/proj/xAnda dapat menampilkannya ~proj:xdengan zsh_directory_namemelakukan pemetaan proj:x<=> /opt/myproj/proj/x. Itu juga digunakan oleh Dflag ekspansi parameter. Jadi jika seseorang mengembang ${(D)somevar}, zsh_directory_namefungsi itu akan dipanggil.

Di sini, kami menggunakan ${(D):-},, ${:-}yang ${no_var:-nothing}diperluas ke nothingjika $no_varkosong, jadi ${(D):-}perluas apa-apa saat memanggil zsh_directory_name. zsh_directory_namesebelumnya telah didefinisikan sebagai:

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

Yaitu, pada ekspansi PS1 pertama (setelah prompt pertama), ${(D):-}akan menyebabkan promptsubstopsi tidak disetel (untuk membatalkan -o promptsubst), zsh_directory_name()menjadi tidak terdefinisi (karena kami ingin menjalankannya hanya sekali) $PS1menjadi tidak disetel, dan /path/to/filemenjadi sumber.

${PS1=%m%# }memperluas (dan menetapkan $PS1) ke %m%#kecuali PS1 sudah didefinisikan (misalnya dengan /path/to/filesetelah unset), dan %m%#kebetulan menjadi nilai default dari PS1.

Stéphane Chazelas
sumber
Ini terlihat sangat mewah dan saya akan mencobanya sesegera mungkin. Saya berharap ini berhasil!
hjkatz