Почніть zsh зі спеціального zshrc


17

Я хочу мати змогу запустити zsh зі спеціального файлу rc, подібного до команди: bash --rc-file /path/to/file

Якщо це неможливо, то чи можна запустити zsh, запустити source /path/to/file, а потім залишитися на тому ж сеансі zsh?

Примітка: Команда zsh --rcs /path/to/fileне працює, принаймні не для мене ...

РЕДАКТУВАННЯ: В цілому я хочу мати змогу зробити наступне: sshна віддалений сервер "example.com", запустіть zsh, sourceмоя конфігурація знаходиться на /path/to/file, все в 1 команді. Тут я боровся, тим більше, що я краще не пишу над файлами конфігурації на віддаленій машині.


1
Привіт, Кац, ласкаво просимо на unix.SE. Я відредагував ваше запитання, щоб додати трохи форматування, яке полегшує читання. Ви можете натиснути «редагувати», щоб побачити, як це працює. Я також видалив додаткові речі, наприклад "Дякую" та ваш підпис (усі повідомлення в мережі Stack Exchange автоматично підписуються).
пр

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 для пошуку іншого набору точкових файлів.

Як підказує сторінка man, 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 -fі тоді source /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_name. zsh_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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.