Inicie zsh con un zshrc personalizado

17

Quiero poder iniciar zsh con un archivo rc personalizado similar al comando: bash --rc-file /path/to/file

Si esto no es posible, ¿es posible iniciar zsh, ejecutar source /path/to/filey luego permanecer en la misma sesión de zsh?

Nota: El comando zsh --rcs /path/to/fileno funciona, al menos no para mí ...

EDITAR: En su totalidad, deseo poder hacer lo siguiente: ssha un servidor remoto "example.com", ejecutar zsh, sourcemi configuración ubicada en /path/to/file, todo en 1 comando. Aquí es donde tuve problemas, especialmente porque prefiero no escribir sobre ningún archivo de configuración en la máquina remota.

hjkatz
fuente
1
Hola Katz, bienvenido a unix.SE. Edité su pregunta para agregar un formato que la haga (ligeramente) más fácil de leer. Puede hacer clic en "editar" para ver cómo funciona. También he eliminado algunas cosas adicionales, como "Gracias" y su firma (todas las publicaciones en la red de Stack Exchange se firman automáticamente).
Dres
1
¡Gracias, ahora aprendí a escribir code as such!
hjkatz

Respuestas:

18

De las páginas del 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.

por lo que debería poder establecer la variable de entorno ZDOTDIRen un nuevo directorio para que zsh busque un conjunto diferente de archivos de puntos.

Como sugiere la página del manual, RCSy GLOBAL_RCSno son rutas a archivos rc, ya que está intentando utilizarlos, sino más bien opciones que puede habilitar o deshabilitar. Entonces, por ejemplo, la bandera --rcshabilitará la RCSopción, causando que zsh lea de los archivos rc. Puede usar los siguientes indicadores de línea de comandos para zsh para habilitar o deshabilitar RCSo GLOBAL_RCS:

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

Para responder a su otra pregunta:

¿es posible iniciar zsh, ejecutar "source / path / to / file" y luego permanecer en la misma sesión de zsh?

Sí, esto es bastante fácil de acuerdo con las instrucciones anteriores. Solo corre zsh -d -fy luego source /path/to/zshrc.

jayhendren
fuente
Como esto funciona según mi pregunta, no mencioné que solo puedo ejecutar 1 comando. Esto no satisface para qué deseo usar esto (un ssh personalizado con mis configuraciones personales). El problema radica en que la ejecución zsh -d -f; source /path/to/filenunca ejecuta el segundo comando en la primera sesión de zsh hasta que sale.
hjkatz
En su totalidad, deseo poder hacer lo siguiente. ssha un servidor remoto "example.com", ejecute zsh, sourcemi configuración ubicada en /path/to/file, todo en 1 comando. Aquí es donde tuve problemas, especialmente porque prefiero no escribir sobre ningún archivo de configuración en la máquina remota. Gracias por tu respuesta sin embargo!
hjkatz
parece que su problema no está en usar un zshrc personalizado sino en no saber cómo usar un shell sobre ssh. Si ejecuta ssh host "zsh -d -f; source /path/to/file", ssh se ejecutará primero zshen el host remoto, luego, source ...después de que salga el shell zsh. En cambio, lo que desea hacer es ssh -t host zsh -d -fcolocarlo en un shell interactivo en el host remoto, o si no quiere un shell interactivo, hágalo ssh host zsh -d -f -c \"source /path/to/file\; other command\; ... \".
jayhendren
No, entiendo cómo funciona ssh con shells interactivos. El problema es que correr ssh -t host "zsh -d -f; source /path/to/fileme deja en un zshshell interactivo (y estéril) .
hjkatz
1
Ya te dije por qué es esto y cómo solucionarlo. Cuando ejecuta ssh -t host "zsh -d -f; source /path/to/file", el comando source...NO se ejecuta dentro del shell zsh. Se ejecuta en su shell de inicio de sesión después de que se cierra el shell zsh. Para probar esto, corre ssh host "zsh; echo foo". Verá la salida "foo" después de salir del shell zsh.
jayhendren
4

mientras que con ZDOTDIR, puede indicar zshque interprete un archivo llamado .zshrcen cualquier directorio de su elección, hacer que interprete cualquier archivo de su elección (no necesariamente llamado .zshrc) resulta bastante difícil.

En sho kshemulación, zshevalúa $ENV; para que puedas agregar emulate zshen la parte superior de tu /path/to/filey hacer:

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

Otro enfoque muy complicado puede ser:

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

Ese merece un poco de explicación.

${foo::=value}es una expansión variable que realmente establece $foo . $functionses una matriz asociativa especial que asigna nombres de funciones a sus definiciones.

Con la promptsubstopción, las variables $PS1se expanden. Entonces, en el primer aviso, las variables en esa PS1 se expandirán.

La zsh_directory_namefunción es una función especial que ayuda a expandir ay ~fooal /path/to/somethingrevés. Que se utiliza, por ejemplo, con %~la pronta por lo que si el directorio actual es /opt/myproj/proj/xque puede mostrarlo como ~proj:xpor tener zsh_directory_namehacer el mapeo proj:x<=> /opt/myproj/proj/x. Eso también lo usa la Dbandera de expansión de parámetros. Entonces, si uno se expande ${(D)somevar}, esa zsh_directory_namefunción se llamará.

Aquí, estamos usando ${(D):-}, ${:-}que se ${no_var:-nothing}expande a nothingsi $no_varestá vacío, por lo que se ${(D):-}expande a nada mientras se llama zsh_directory_name. zsh_directory_namese ha definido previamente como:

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

Es decir, en la primera expansión de PS1 (en el primer aviso), ${(D):-}hará que la promptsubstopción se desactive (para cancelar -o promptsubst), zsh_directory_name()que no esté definida (ya que queremos ejecutarla solo una vez), $PS1que no se establezca y /path/to/fileque se obtenga.

${PS1=%m%# }se expande (y se asigna $PS1) a %m%#menos que PS1 ya esté definido (por ejemplo, /path/to/filedespués de unset), y %m%#resulta ser el valor predeterminado de PS1.

Stéphane Chazelas
fuente
Esto parece bastante extravagante y lo intentaré lo antes posible. ¡Espero que esto funcione!
hjkatz