Starten Sie zsh mit einem benutzerdefinierten zshrc

16

Ich möchte in der Lage sein, zsh mit einer benutzerdefinierten rc-Datei zu starten, die dem folgenden Befehl ähnelt: bash --rc-file /path/to/file

Wenn dies nicht möglich ist, ist es dann möglich, zsh zu starten, auszuführen source /path/to/fileund dann in derselben zsh-Sitzung zu bleiben?

Hinweis: Der Befehl zsh --rcs /path/to/filefunktioniert nicht, zumindest nicht für mich ...

EDIT: In seiner Gesamtheit Ich möchte der Lage sein , folgendes zu tun: sshzu einem Remote - Server „example.com“, laufen zsh, sourcemeine Konfiguration befindet sich auf /path/to/file, alle in - 1 - Befehl. Dies ist, wo ich gekämpft habe, vor allem, weil ich lieber keine Konfigurationsdateien auf dem Remotecomputer überschreiben möchte.

hjkatz
quelle
1
Hallo Katz, willkommen bei unix.SE. Ich habe Ihre Frage bearbeitet, um eine Formatierung hinzuzufügen, die das Lesen (etwas) erleichtert. Sie können auf "Bearbeiten" klicken, um zu sehen, wie es funktioniert. Ich habe auch einige zusätzliche Dinge entfernt, wie "Danke" und Ihre Signatur (alle Posts im Stack Exchange-Netzwerk werden automatisch signiert).
drs
1
Danke, ich habe jetzt das Tippen gelernt code as such!
hjkatz

Antworten:

17

Aus den Manpages:

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.

Sie sollten also in der Lage sein, die Umgebungsvariable ZDOTDIRauf ein neues Verzeichnis zu setzen, damit zsh nach einem anderen Satz von Punktdateien sucht.

Als der Mann Seite schon sagt, RCSund GLOBAL_RCSsind nicht Pfade zu rc - Dateien, wie Sie sie versuchen , zu verwenden, sondern Optionen können Sie oder deaktivieren aktivieren. So --rcsaktiviert das Flag beispielsweise die RCSOption, sodass zsh aus RC-Dateien liest. Sie können die folgenden Befehlszeilenflags verwenden, um zsh zu aktivieren oder zu deaktivieren RCSoder GLOBAL_RCS:

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

So beantworten Sie Ihre andere Frage:

Ist es möglich, zsh zu starten, "source / path / to / file" auszuführen und dann in derselben zsh-Sitzung zu bleiben?

Ja, das ist nach den obigen Anweisungen ziemlich einfach. Einfach rennen zsh -d -fund dann source /path/to/zshrc.

Jayhendren
quelle
Da dies gemäß meiner Frage funktioniert, habe ich nicht erwähnt, dass ich nur 1 Befehl ausführen kann. Dies entspricht nicht dem, wofür ich dies verwenden möchte (eine benutzerdefinierte SSH mit meinen persönlichen Konfigurationen). Das Problem liegt darin, dass das zsh -d -f; source /path/to/fileAusführen des zweiten Befehls in der ersten Sitzung von zsh erst nach dem Beenden ausgeführt wird.
hjkatz
In seiner Gesamtheit möchte ich in der Lage sein, das Folgende zu tun. sshzu einem Remote - Server „example.com“, laufen zsh, sourcemeine Konfiguration befindet sich auf /path/to/file, alle in - 1 - Befehl. Dies ist, wo ich gekämpft habe, vor allem, weil ich lieber keine Konfigurationsdateien auf dem Remotecomputer überschreiben möchte. Vielen Dank für Ihre Antwort!
hjkatz
Es scheint, dass Ihr Problem nicht darin besteht, ein benutzerdefiniertes zshrc zu verwenden, sondern nicht zu wissen, wie man eine Shell über ssh verwendet. Wenn Sie ausführen ssh host "zsh -d -f; source /path/to/file", wird ssh zuerst zshauf dem Remote-Host ausgeführt und dann, source ...nachdem die zsh-Shell beendet wurde. Sie möchten stattdessen ssh -t host zsh -d -fin eine interaktive Shell auf dem Remotehost ziehen oder, wenn Sie keine interaktive Shell möchten, dies tun ssh host zsh -d -f -c \"source /path/to/file\; other command\; ... \".
Jayhendren
Nein, ich verstehe, wie ssh mit interaktiven Shells funktioniert. Das Problem ist, dass ssh -t host "zsh -d -f; source /path/to/filemich das Laufen in eine interaktive (und unfruchtbare) zshShell stürzt .
hjkatz
1
Ich habe Ihnen bereits gesagt, warum dies so ist und wie Sie es beheben können. Bei der Ausführung ssh -t host "zsh -d -f; source /path/to/file"wird der Befehl source...NICHT in der zsh-Shell ausgeführt. Es wird in Ihrer Login-Shell ausgeführt, nachdem die zsh-Shell beendet wurde. Führen Sie den Befehl aus, um dies zu testen ssh host "zsh; echo foo". Sie sehen die Ausgabe "foo", nachdem Sie die zsh-Shell verlassen haben.
Jayhendren
4

Während mit ZDOTDIR, können Sie sagen zsh eine Datei, die .zshrcin einem beliebigen Verzeichnis Ihrer Wahl aufgerufen wird, interpretiert werden soll. Die Interpretation einer beliebigen Datei (die nicht unbedingt aufgerufen wird .zshrc) ist jedoch recht schwierig.

In shoder kshEmulation, zshwertet aus $ENV; so können Sie emulate zsham oberen Rand Ihrer hinzufügen/path/to/file und tun:

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

Ein anderer sehr komplizierter Ansatz könnte sein:

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

Das verdient eine Erklärung.

${foo::=value}ist eine variable Erweiterung, die tatsächlich setzt $foo .$functionsist ein spezielles assoziatives Array, das Funktionsnamen ihren Definitionen zuordnet.

Mit der promptsubstOption können Variablen in$PS1 erweitert. Bei der ersten Aufforderung werden die Variablen in dieser PS1 erweitert.

Die zsh_directory_nameFunktion ist eine spezielle Funktion, die beim Erweitern des ~fooVor- /path/to/somethingund Rücklaufs hilft . Dies wird zum Beispiel %~in der Eingabeaufforderung mit verwendet, damit Sie das aktuelle Verzeichnis /opt/myproj/proj/xanzeigen können, ~proj:xindem zsh_directory_nameSie das Mapping durchführen proj:x<=> /opt/myproj/proj/x. Dies wird auch vom DParametererweiterungsflag verwendet. Wenn man also expandiert ${(D)somevar}, wird diese zsh_directory_nameFunktion aufgerufen.

Hier verwenden wir ${(D):-}, ${:-}, das ist ${no_var:-nothing}ERWEITERT nothingwenn $no_varleer ist, so ${(D):-}zu nichts expandiert beim Telefonieren zsh_directory_name. zsh_directory_namewurde bisher definiert als:

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

Das heißt, bei der ersten PS1-Erweiterung (bei der ersten Eingabeaufforderung) ${(D):-}wird die promptsubstOption deaktiviert (um den Vorgang abzubrechen -o promptsubst), zsh_directory_name()undefiniert (da wir sie nur einmal ausführen möchten) $PS1und deaktiviert/path/to/file als Quelle ausgewählt.

${PS1=%m%# }wird erweitert (und zugewiesen $PS1), %m%#sofern PS1 nicht bereits definiert wurde (z. B. /path/to/filenach dem unset) und %m%#zufällig der Standardwert von ist PS1.

Stéphane Chazelas
quelle
Das sieht ziemlich extravagant aus und ich werde es so schnell wie möglich versuchen. Ich bin zuversichtlich, dass dies funktioniert!
hjkatz