Inicie o zsh com um zshrc personalizado

17

Quero poder iniciar o zsh com um arquivo rc personalizado semelhante ao comando: bash --rc-file /path/to/file

Se isso não for possível, é possível iniciar o zsh, executar source /path/to/filee permanecer na mesma sessão do zsh?

Nota: O comando zsh --rcs /path/to/filenão funciona, pelo menos não para mim ...

EDIT: Na íntegra, desejo poder fazer o seguinte: sshem um servidor remoto "example.com", execute zsh, sourceminha configuração localizada em /path/to/file, tudo em 1 comando. É aqui que luto, principalmente porque prefiro não escrever sobre nenhum arquivo de configuração na máquina remota.

hjkatz
fonte
1
Olá Katz, bem-vindo ao unix.SE. Editei sua pergunta para adicionar uma formatação que a torna (um pouco) mais fácil de ler. Você pode clicar em "editar" para ver como funciona. Também removi algumas coisas extras, como "Obrigado" e sua assinatura (todas as postagens na rede Stack Exchange são assinadas automaticamente).
drs 23/05
1
Obrigado, agora eu aprendi a digitar code as such!
Hjkatz 23/05

Respostas:

17

Nas páginas do 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.

portanto, você poderá definir a variável de ambiente ZDOTDIRcomo um novo diretório para que o zsh procure um conjunto diferente de arquivos de ponto.

Como a página de manual sugere, RCSe GLOBAL_RCSnão são caminhos para arquivos rc, como você está tentando usá-los, mas opções que podem ser ativadas ou desativadas. Portanto, por exemplo, o sinalizador --rcsativará a RCSopção, fazendo com que o zsh leia os arquivos rc. Você pode usar os seguintes sinalizadores de linha de comando no zsh para ativar ou desativar RCSou GLOBAL_RCS:

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

Para responder sua outra pergunta:

é possível iniciar o zsh, executar "source / path / to / file" e permanecer na mesma sessão do zsh?

Sim, isso é bastante fácil de acordo com as instruções acima. Apenas corra zsh -d -fe depois source /path/to/zshrc.

jayhendren
fonte
Como isso funciona de acordo com minha pergunta, não mencionei que só posso executar 1 comando. Isso não satisfaz o que eu desejo usar isso (um ssh personalizado com minhas configurações pessoais). O problema reside no fato de a execução zsh -d -f; source /path/to/filenunca executar o segundo comando na primeira sessão do zsh até sair.
Hjkatz 23/05
Na íntegra, desejo poder fazer o seguinte. sshpara um servidor remoto "example.com", execute zsh, sourceminha configuração localizada em /path/to/file, tudo em 1 comando. É aqui que luto, principalmente porque prefiro não escrever sobre nenhum arquivo de configuração na máquina remota. Obrigado por você responder!
Hjkatz 23/05
Parece que seu problema não está em usar um zshrc personalizado, mas em não saber como usar um shell sobre ssh. Se você executar ssh host "zsh -d -f; source /path/to/file", o ssh será executado primeiro zshno host remoto e source ...depois que o shell zsh sair. Em vez disso, o que você deseja fazer é ssh -t host zsh -d -fsoltar em um shell interativo no host remoto ou, se você não quiser um shell interativo, faça ssh host zsh -d -f -c \"source /path/to/file\; other command\; ... \".
Jayhendren # 23/14
Não, eu entendo como o ssh funciona com shells interativos. O problema é que correr ssh -t host "zsh -d -f; source /path/to/fileme deixa em um zshshell interativo (e estéril) .
Hjkatz 23/05
1
Eu já lhe disse por que isso é e como corrigi-lo. Quando você executa ssh -t host "zsh -d -f; source /path/to/file", o comando source...NÃO é executado dentro do shell zsh. É executado no seu shell de login após a saída do zsh. Para testar isso, execute ssh host "zsh; echo foo". Você verá a saída "foo" depois de sair do shell zsh.
Jayhendren # 23/14
4

enquanto com o ZDOTDIR, você pode dizer zshpara interpretar um arquivo chamado .zshrcem qualquer diretório de sua escolha, e interpretar qualquer arquivo de sua escolha (não necessariamente chamado .zshrc) se mostra bastante difícil.

Em shou kshemulação, zshavalia $ENV; para que você possa adicionar emulate zshna parte superior do seu /path/to/filee fazer:

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

Outra abordagem muito complicada poderia 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

Esse merece uma explicação.

${foo::=value}é uma expansão variável que realmente define $foo . $functionsé uma matriz associativa especial que mapeia nomes de funções para suas definições.

Com a promptsubstopção, as variáveis ​​in $PS1são expandidas. Portanto, no primeiro prompt, as variáveis ​​nesse PS1 serão expandidas.

A zsh_directory_namefunção é uma função especial que ajuda a expandir o ~foopara /path/to/somethinge o inverso. Isso é usado, por exemplo, %~no prompt para que, se o diretório atual estiver, /opt/myproj/proj/xvocê possa exibi-lo como ~proj:xfazendo zsh_directory_nameo mapeamento proj:x<=> /opt/myproj/proj/x. Isso também é usado pelo Dsinalizador de expansão de parâmetro. Portanto, se alguém se expandir ${(D)somevar}, essa zsh_directory_namefunção será chamada.

Aqui, estamos usando ${(D):-}, ${:-}que é ${no_var:-nothing}se expande para nothingse $no_varestá vazio, então ${(D):-}se expande para nada ao chamar zsh_directory_name. zsh_directory_namefoi definido anteriormente como:

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

Ou seja, na primeira expansão do PS1 (no primeiro prompt), ${(D):-}a promptsubstopção será desabilitada (para cancelar a -o promptsubst), zsh_directory_name()indefinida (como queremos executá-la apenas uma vez) $PS1, desabilitada e /path/to/fileoriginada.

${PS1=%m%# }expande (e atribui $PS1) a %m%#menos que o PS1 já esteja definido (por exemplo, /path/to/fileapós o unset) e %m%#passa a ser o valor padrão de PS1.

Stéphane Chazelas
fonte
Isso parece bastante extravagante e vou tentar o mais rápido possível. Espero que isso funcione!
Hjkatz 23/05