使用自定义zshrc启动zsh


17

我希望能够使用类似于命令的自定义rc文件启动zsh: bash --rc-file /path/to/file

如果这不可能,那么是否可以启动zsh,运行source /path/to/file,然后停留在同一zsh会话中?

注意:该命令zsh --rcs /path/to/file不起作用,至少对我而言不起作用...

编辑:整体而言,我希望能够执行以下操作: ssh在远程服务器“ example.com”上,运行zshsource我的配置位于/path/to/file,所有命令为1。这就是我一直在努力的地方,尤其是因为我不想覆盖远程计算机上的任何配置文件。


1
嗨,Katz,欢迎来到unix.SE。我已经编辑了您的问题,添加了一些使其(略)易于阅读的格式。您可以单击“编辑”以查看其工作方式。我还删除了一些其他内容,例如“谢谢”和您的签名(Stack Exchange网络上的所有帖子都自动签名)。
DRS

1
谢谢,我现在已经学会了打字code as such
hjkatz 2014年

Answers:


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查找不同的点文件集。

由于该男子页显示,RCSGLOBAL_RCS没有路径RC文件,您正在尝试使用它们,而是选项,你可以启用或禁用。因此,例如,该标志--rcs将启用该RCS选项,从而导致zsh从rc文件读取。您可以使用以下命令行标志对zsh启用或禁用RCSGLOBAL_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 2014年

我希望能够整体上做到以下几点。 ssh到远程服务器“ example.com”,运行zshsource我的配置位于/path/to/file,所有命令为1。这就是我一直在努力的地方,尤其是因为我不想覆盖远程计算机上的任何配置文件。谢谢您的回答!
hjkatz 2014年

似乎您的问题不是在使用自定义zshrc,而是在不知道如何在ssh上使用shell。如果运行ssh host "zsh -d -f; source /path/to/file",那么ssh将首先zsh在远程主机上运行,然后source ...在zsh shell退出之后运行。相反,您想要做的是ssh -t host zsh -d -f放入远程主机上的交互式外壳,或者如果您不想使用交互式外壳,请执行do ssh host zsh -d -f -c \"source /path/to/file\; other command\; ... \"
jayhendren 2014年

不,我不知道ssh如何与交互式shell一起工作。问题是跑步使ssh -t host "zsh -d -f; source /path/to/file我陷入了交互式(贫瘠的)zsh外壳中。
hjkatz 2014年

1
我已经告诉过您为什么会这样以及如何解决它。运行时ssh -t host "zsh -d -f; source /path/to/file",该命令source...不在zsh shell内运行。它在zsh Shell退出后在您的登录Shell中运行。要对此进行测试,请运行ssh host "zsh; echo foo"。从zsh shell退出后,您将看到输出“ foo” 。
jayhendren 2014年

4

在使用ZDOTDIR时,您可以告诉zsh您解释.zshrc在您选择的任何目录中调用的文件,.zshrc事实证明让它解释您选择的任何文件(不一定称为)非常困难。

shksh模拟中,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将扩展变量in 。因此,在第一个提示下,该PS1中的变量将被扩展。

zsh_directory_name功能是一种特殊的功能,有助于扩大~foo/path/to/something和反向。例如,%~在提示中使用,这样,如果当前目录是/opt/myproj/proj/x您可以~proj:x通过zsh_directory_name执行映射proj:x<=> 来显示它/opt/myproj/proj/xD参数扩展标志也使用了该参数。因此,如果扩展${(D)somevar},该zsh_directory_name函数将被调用。

在这里,我们使用${(D):-}${:-}${no_var:-nothing}膨胀到nothing,如果$no_var是空的,所以${(D):-}什么也不扩展,同时呼吁zsh_directory_namezsh_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(例如,在之前),否则扩展(并分配$PS1)到,并且碰巧是的默认值。%m%#/path/to/fileunset%m%#PS1


这看起来很奢侈,我会尽快尝试。我希望这能奏效!
hjkatz 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.