Inizia zsh con uno zshrc personalizzato


17

Voglio essere in grado di avviare zsh con un file rc personalizzato simile al comando: bash --rc-file /path/to/file

Se ciò non è possibile, è possibile avviare zsh, eseguirlo source /path/to/file, quindi rimanere nella stessa sessione zsh?

Nota: il comando zsh --rcs /path/to/filenon funziona, almeno non per me ...

EDIT: nella sua interezza desidero essere in grado di fare quanto segue: sshsu un server remoto "esempio.com", eseguire zsh, la sourcemia configurazione si trova in /path/to/file, tutto in 1 comando. È qui che ho faticato, soprattutto perché preferirei non scrivere su alcun file di configurazione sul computer remoto.


1
Ciao Katz, benvenuto su unix.SE. Ho modificato la tua domanda per aggiungere un po 'di formattazione che rende (leggermente) più facile da leggere. Puoi fare clic su "modifica" per vedere come funziona. Ho anche rimosso alcune cose extra, come "Grazie" e la tua firma (tutti i post sulla rete Stack Exchange vengono automaticamente firmati).
Dott.

1
Grazie, ora ho imparato a digitare code as such!
hjkatz,

Risposte:


18

Dalle pagine man:

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.

quindi dovresti essere in grado di impostare la variabile d'ambiente ZDOTDIRin una nuova directory per fare in modo che zsh cerchi un diverso set di dotfile.

Come suggerisce la pagina man, RCSe GLOBAL_RCSnon sono percorsi per i file rc, come si sta tentando di usarli, ma piuttosto opzioni che è possibile abilitare o disabilitare. Quindi, ad esempio, il flag --rcsabiliterà l' RCSopzione, facendo sì che zsh legga dai file rc. È possibile utilizzare i seguenti flag della riga di comando su zsh per abilitare o disabilitare RCSo GLOBAL_RCS:

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

Per rispondere alla tua altra domanda:

è possibile avviare zsh, eseguire "source / path / to / file", quindi rimanere nella stessa sessione zsh?

Sì, questo è abbastanza facile secondo le indicazioni sopra. Corri zsh -d -fe poi source /path/to/zshrc.


Dato che funziona secondo la mia domanda, non ho menzionato che posso eseguire solo 1 comando. Questo non soddisfa ciò per cui desidero utilizzarlo (un ssh personalizzato con le mie configurazioni personali). Il problema risiede nel fatto che l'esecuzione zsh -d -f; source /path/to/filenon esegue mai il secondo comando nella prima sessione di zsh fino all'uscita.
hjkatz,

Nella sua interezza, desidero poter fare quanto segue. sshsu un server remoto "esempio.com", esegui zsh, la sourcemia configurazione si trova in /path/to/file, comando all in 1. È qui che ho faticato, soprattutto perché preferirei non scrivere su alcun file di configurazione sul computer remoto. Grazie per la tua risposta però!
hjkatz,

sembra che il tuo problema non sia nell'uso di uno zshrc personalizzato ma nel non sapere come usare una shell su ssh. Se si esegue ssh host "zsh -d -f; source /path/to/file", quindi ssh verrà eseguito prima zshsull'host remoto, quindisource ... dopo l'uscita della shell zsh. Invece, quello che vuoi fare è ssh -t host zsh -d -fdi cadere in una shell interattiva sull'host remoto, o se non vuoi una shell interattiva, fallo ssh host zsh -d -f -c \"source /path/to/file\; other command\; ... \".
Jayhendren,

No, capisco come funziona ssh con le shell interattive. Il problema è che correre ssh -t host "zsh -d -f; source /path/to/filemi fa cadere in una zshshell interattiva (e sterile) .
hjkatz,

1
Ti ho già detto perché questo è e come risolverlo. Quando si esegue ssh -t host "zsh -d -f; source /path/to/file", il comando source...NON viene eseguito all'interno della shell zsh. Viene eseguito nella shell di accesso dopo la chiusura della shell zsh. Per provarlo, esegui ssh host "zsh; echo foo". Vedrai l'output "pippo" dopo essere uscito dalla shell zsh.
Jayhendren,

4

mentre con ZDOTDIR, puoi dire zshdi interpretare un file chiamato .zshrcin qualsiasi directory di tua scelta, farlo interpretare qualsiasi file di tua scelta (non necessariamente chiamato .zshrc) si rivela abbastanza difficile.

In sho kshemulazione, zshvaluta $ENV; in modo da poter aggiungere emulate zshnella parte superiore del tuo /path/to/filee fare:

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

Un altro approccio molto contorto potrebbe essere:

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

Quello merita una spiegazione.

${foo::=value}è un'espansione variabile che effettivamente imposta $foo . $functionsè una matrice associativa speciale che associa i nomi delle funzioni alle loro definizioni.

Con l' promptsubstopzione, le variabili in $PS1vengono espanse. Quindi, al primo prompt, le variabili in quella PS1 verranno espanse.

La zsh_directory_namefunzione è una funzione speciale che aiuta ad espandere il ~fooverso /path/to/somethinge il contrario. Questo è usato ad esempio con%~Viene nel prompt in modo che se la directory corrente è /opt/myproj/proj/xpossibile visualizzarla come ~proj:xeseguendo zsh_directory_nameil mapping proj:x<=> /opt/myproj/proj/x. Viene utilizzato anche dal Dflag di espansione dei parametri. Quindi se uno si espande ${(D)somevar}, quella zsh_directory_namefunzione verrà chiamata.

Qui, stiamo usando ${(D):-}, ${:-}cioè${no_var:-nothing} espande a nothingse $no_varè vuoto, così ${(D):-}si espande per niente durante la chiamata zsh_directory_name. zsh_directory_nameè stato precedentemente definito come:

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

Cioè, alla prima espansione di PS1 (al primo prompt), ${(D):-} l' promptsubstopzione verrà disattivata (per annullare la -o promptsubst), zsh_directory_name()indefinita (come vogliamo eseguirla solo una volta) $PS1per essere annullata e /path/to/filereperita.

${PS1=%m%# }si espande (e si assegna $PS1) a %m%#meno che PS1 non sia già stato definito (ad esempio da /path/to/filedopo il unset), e %m%#risulta essere il valore predefinito di PS1.


Sembra abbastanza stravagante e lo proverò al più presto. Spero che funzioni!
hjkatz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.