web-dev-qa-db-ja.com

カスタムzshrcでzshを起動します

コマンドに似たカスタムrcファイルでzshを起動できるようにしたい: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つのコマンドで。これは私が苦労した場所です。特に、リモートマシンの構成ファイルを上書きしたくないからです。

20
hjkatz

マニュアルページから:

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ページが示唆しているように、RCSGLOBAL_RCSは、それらを使用しようとしているため、rcファイルへのパスではなく、有効または無効にできるオプションです。したがって、たとえば、フラグ--rcsRCSオプションを有効にし、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を実行するだけです。

21
jayhendren

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}_は、実際にはsets _$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}_が空の場合、_$no_var_はnothingに展開されるため、${(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が既に定義されていない限り(たとえば、unsetの後の_$PS1_によって_%m%#_を展開し、_/path/to/file_に割り当てます)、_%m%#_はたまたま_PS1_のデフォルト値です。

5