Fish-shell: Die Reaktionsfähigkeit der Fische im interaktiven Modus ist langsam

Erstellt am 22. Okt. 2016  ·  49Kommentare  ·  Quelle: fish-shell/fish-shell

  • [x] Haben Sie überprüft, ob das Problem mit Fischen 2.3.1 auftritt?
  • [x] Fisch ohne Anpassungen von Drittanbietern ausprobiert _(check sh -c 'env HOME=$(mktemp -d) fish' )_?

Fischversion installiert _( fish --version )_:
2.3.1

Verwendetes Betriebssystem/Terminal :
Slackware Linux, 64-Bit, -aktuelle Serie

Ausgabe von "uname -a":

Linux [Hostname] 4.4.23 #1 SMP Fr 30. September 21:14:07 CDT 2016 x86_64 Intel(R) Core(TM) i7-4510U CPU @ 2,00 GHz GenuineIntel GNU/Linux

Terminal: yakuake, mit konsolepart5 (KDE Plasma)

Sprechen Sie hier über das Problem.

Ich mag Fisch und habe es zur Standard-Shell für meinen Benutzer gemacht.
Die bisherige Erfahrung ist in Ordnung, aber ich finde es sehr langsam in seiner Reaktionsfähigkeit im interaktiven Gebrauch.

Meistens wird die Antwort zwischen einem eingegebenen Befehl und seiner Antwort in _Sekunden_ gemessen.

Selbst das Löschen des Terminalbildschirms durch Drücken von Strg-L dauert _zwei Sekunden_ (!)

Und das, obwohl ich eine einigermaßen schnelle CPU (siehe uname-Ausgabe oben) und 12 GB RAM habe. In dieser Maschine fliegt Bash, aber Fisch nicht.

Reproduktionsschritte

  1. Schritt eins

(nicht nötig)

Nochmals vielen Dank für die Entwicklung von Fisch. Ich denke, es ist ein fantastisches Produkt. Ich hoffe, Sie verbessern es weiter.

question

Alle 49 Kommentare

Das scheint wirklich ungewöhnlich zu sein. Haben Sie etwas Seltsames in Ihrer Konfiguration, insbesondere Event-Handler? Irgendwelche "Frameworks" - OMF oder Fischer oder so?

Kannst du das in einem anderen Terminal testen?

Ist es nur beim _starten_ eines Befehls oder beim _tippen_?

Verwenden Sie auch NFS oder ein anderes Dateisystem, das langsam sein könnte?

Hallo @faho , danke für die Antwort.

  1. Ich habe keine seltsame Konfiguration. Ich verwende nur Fisch als Vanille, wie ich kann. Und Slackware ist so nah wie möglich am Bare Metal. Auch kein OMF oder Fischer.
  2. Getestet in xterm, mate-terminal, xfce4-terminal, QTerminal, rxvt, sakura und cool-retro-term. Gleiches Verhalten beobachtet. Selbst wenn ich an der Eingabeaufforderung nur einen Wagenrücklauf drücke (dh kein Befehl eingegeben, nur ein Wagenrücklauf), dauert es manchmal zwischen 1 und 2 Sekunden, bis die Eingabeaufforderung wieder erscheint. In rxvt (und nur darauf) habe ich ein "Tofu" -Zeichen beobachtet, das eingefügt wurde, nachdem ich Wagenrücklauf gedrückt hatte und bevor Fish die Eingabeaufforderung erneut anzeigt.
  3. Beim Starten eines Befehls. Das heißt, die langsame Reaktion geschieht bei Antworten, die Fisch anzeigen sollte, _nachdem der Bediener den Wagenrücklauf gedrückt hat.
  4. Nein, ich verwende kein NFS. Ich verwende ext4 auf einem SSD-Laufwerk. Nicht wirklich langsam und tatsächlich zeigt sich diese Langsamkeit bei der Verwendung von bash oder ksh überhaupt nicht.

Danke nochmal für die nette Antwort.

Könnten Sie eine Bildschirmaufnahme auf asciinema.org machen? Oder andernfalls?

Die wahrscheinlichste Sache ist, dass die Eingabeaufforderung dies verlangsamt - Sie haben Ihr $HOME nicht zufällig in einem hg-Repository?

Dies kann getestet werden, indem die Funktion fish_prompt neu definiert wird, z. B. function fish_prompt; echo ">"; end .

Wenn das nicht der Fall ist, hast du den vi-Modus aktiviert?

Auch eine Aufzeichnung (Text oder Gif) einer fish -d5 Sitzung kann hilfreich sein.

Werde versuchen.
Überprüfen Sie dies: https://asciinema.org/a/f52wznwl2pxrzfb2m68a4qoc7

Dies ist eine Aufzeichnung von Fisch -d5: https://asciinema.org/a/5xix93qsbkisvokwy4ge4guio

_hg-Repository_: keine Ahnung, was das ist.

Durch die Neudefinition von fish_prompt wird es jetzt _schneller_ und die Reaktionsfähigkeit sieht ähnlich oder gleich aus wie normal. Bingo!

Es scheint also, dass die Eingabeaufforderung dafür verantwortlich ist. Ich habe gerade eine der vorgeschlagenen Eingabeaufforderungen in fish_config prompt . Sie können in meinen Aufnahmen von asciinema.org die von mir gewählte sehen.

Schöne Detektivarbeit. Ich frage mich, ob mercurial wie git ist, das auf der Suche nach einem Repository in der übergeordneten Verzeichnishierarchie nach oben geht.

@ridiculousfish : Ich denke nicht, dass es Quecksilber ist, obwohl das ziemlich langsam sein kann. (Die Hauptkosten sind normalerweise nur der Start, weshalb ich benutzerdefinierten Code geschrieben habe, um festzustellen, ob Sie sich in einem Repository befinden.)

@thegreyshadow : Welche Eingabeaufforderung hast du ausgewählt? Können Sie fish --profile prompt.prof -c 'fish_prompt' ausführen und "prompt.prof" hochladen?

@faho Ich habe diesen hier gewählt: [eduardo<strong i="6">@loli</strong> ~]$ '. It's one of the suggestions after typing fish_config prompt`. Ich möchte nicht einmal, dass der Hostname angezeigt wird. Ich befinde mich noch in der sehr frühen Phase der Lernkurve (im Klartext: i'm a total n00b).

prompt.prof wurde hochgeladen, nachdem es aufgrund der Einschränkungen von github in txt konvertiert wurde
prompt.prof.txt
.

Das habe ich auch gemacht:

[ eduardo@loli ~]$ type fish_prompt
fish_prompt ist eine Funktion mit Definition
function fish_prompt --description 'Prompt ausschreiben'
set -l home_escaped (echo -n $HOME | sed 's/\//\\//g')
set -l pwd (echo -n $PWD | sed "s/^$home_escaped/~/" | sed 's/ /%20/g')
set -l prompt_symbol ''
Schalter $USER
Gehäusewurzel toor
setze prompt_symbol '#'
Fall '*'
setze prompt_symbol '$'
Ende
printf "[%s@%s %s%s%s]%s " $USER (hostname -s) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol
Ende
[ eduardo@loli ~]$

Heureka!

Das habe ich tatsächlich schon einmal gesehen! sort -nk 2 prompt.prof.txt zeigt die Zeilen nach Summenzeit sortiert an, und es zeigt Folgendes:

55336   55424   --> hostname -s
196     55873   -> printf "[%s@%s %s%s%s]%s " $USER (hostname -s) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol
112     61290   > fish_prompt

hostname -s . Haben Sie Ihren Hostnamen nicht in /etc/hosts?

Siehe #2854.

hostname -s bringt die Textzeichenfolge "loli"
Ja, ich habe meinen Hostnamen in /etc/hosts.

# For loopbacking.
127.0.0.1               localhost
127.0.0.1               loli.sombragris.org loli

Stimmt /etc/hostname mit /etc/hosts auf Ihrem Hostnamen überein? Hast du ein Hostnamen-Resolver-Setup?

Die Daten besagen, dass hostname -s 90 % Ihrer Promptzeit ausmacht.

# For loopbacking. 127.0.0.1 localhost 127.0.0.1 loli.sombragris.org loli

Ich gehe davon aus, dass das nicht in der gleichen Zeile steht?

Es tut uns leid. Werde versuchen es richtig auszudrücken:

# For loopbacking.
127.0.0.1               localhost
127.0.0.1               loli.sombragris.org loli

Entschuldigen Sie die Unannehmlichkeiten.

Was sagt /etc/HOSTNAME? Anscheinend ist das die Slackware-Datei.

Ausgabe:

[eduardo<strong i="6">@loli</strong> ~]$ cat /etc/HOSTNAME 
loli.sombragris.org
[eduardo<strong i="7">@loli</strong> ~]$ 

Okay, ich bin mir nicht sicher, wie Slack dieses Setup hat, also wäre es besser, wenn Sie in einem Slackware-Forum fragen (ich glaube, linuxquestions.org macht viel Slackware?).

Ich denke, wir haben geklärt, warum Ihre Aufforderung langsam ist, also ist der Fischteil davon gelöst.

@faho Ich stimme zu. Ich brauche nicht einmal, dass mein Hostname angezeigt wird, also werde ich sehen, wie ich ihn loswerden kann.
Es bleibt jedoch die Tatsache, dass in bash diese Verzögerung meiner Meinung nach nicht eintritt. Der Standard-Bash-Prompt von Slackware zeigt den Hostnamen an, aber es gibt keine Verzögerung wie bei Fisch. Aber egal, ist eine Angelegenheit von geringer Bedeutung.

Ich werde sehen, wie ich den Hostnamen in meinem Fisch-Prompt loswerden kann.
Danke für Ihre Geduld! Ich denke, Sie können das Thema schließen.

Es bleibt jedoch die Tatsache, dass in bash diese Verzögerung meiner Meinung nach nicht eintritt. Der Standard-Bash-Prompt von Slackware zeigt den Hostnamen an, aber es gibt keine Verzögerung wie bei Fisch. Aber egal, ist eine Angelegenheit von geringer Bedeutung.

Es tut wahrscheinlich nicht das Äquivalent von hostname -s , oder vielleicht ist der Befehl hostname Slackware nur langsam und die Bash hat eine andere Implementierung?

@faho habe jetzt gerade zwei Dinge gefunden:

  1. Bash hat den Hostnamen als Escape-Sequenz, die in der Eingabeaufforderung verwendet werden könnte: \h -- Überprüfen Sie http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/bash-prompt-escape-sequences.html
  2. Ich habe festgestellt, dass hostname -s _way_ langsamer ist als nur hostname aber beide Befehle geben in meinem System die gleiche Ausgabe.

Danke noch einmal!

@faho Ich möchte nur sagen, dass ich mein spezielles Problem gelöst habe, den Hostnamen loszuwerden:

function fish_prompt --description 'Write out the prompt'
    set -l home_escaped (echo -n $HOME | sed 's/\//\\\\\//g')
    set -l pwd (echo -n $PWD | sed "s/^$home_escaped/~/" | sed 's/ /%20/g')
    set -l prompt_symbol ''
    switch $USER
        case root toor
            set prompt_symbol '#'
        case '*'
            set prompt_symbol '$'
    end
    printf "[%s %s%s%s]%s " $USER (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol
end

Das gibt mir diese Aufforderung:

[eduardo ~]$ 

das ist genau das, was ich in erster Linie wollte.
Nochmals vielen Dank für Ihre Hilfe und Geduld beim Aussortieren.

Vielleicht sollten wir eine elektrische $hostname-Var anbieten.

Vielleicht sollten wir eine elektrische $hostname-Var anbieten.

Fish ruft derzeit nur den Hostnamen für die Benennung der universellen var-Datei ab. Und der Konsens ist, dass wir damit aufhören sollten. Außerdem ist es ziemlich unwahrscheinlich, dass ein gethostname() Aufruf oder ein Äquivalent von fish schneller ist als das Ausführen des hostname Befehls (ohne die paar hundert Mikrosekunden, die zum Starten eines externen Befehls erforderlich sind). Auch in anderen Bereichen, wie dem Abrufen von SCM-Daten (z. B. von Mercurial), gab es einige Probleme mit der prompten Leistung.

Jedes "Reaktionsverhalten"-Problem, an das ich mich erinnern kann, wurde im letzten Jahr geöffnet und beinhaltete die Aufforderung. Ich frage mich also, ob wir vielleicht nicht einfach eine einmalige Warnung ausgeben sollten, wenn die Erstellung der Eingabeaufforderung lange dauert. Sagen Sie mehr als 300 ms.

Ich denke, es ist sicher, dass wir den Hostnamen selbst schneller erhalten als durch Forken eines externen Prozesses. Bedenken Sie auch, dass hostname -s oder hostname nicht überall funktioniert.

Nun, in Slackware wird der Hostname von net-tools 1.6x bereitgestellt. In meinem speziellen Fall führt das Aufrufen von hostname ohne Schalter zum gleichen Ergebnis wie das Aufrufen von hostname -s , aber die Ausführung ist viel schneller.

Asciinema-Link, der das oben genannte zeigt: https://asciinema.org/a/2al3brwb31migfkkwd6sg1hwx

Natürlich können wir den Hostnamen schneller erhalten, indem wir den Aufwand für das Starten eines externen Befehls vermeiden. Verlangsamen Sie und lesen Sie noch einmal, was ich geschrieben habe. Dieser Overhead ist normalerweise belanglos. Außerdem ist die Beschleunigung durch die Vermeidung dieses Overheads völlig irrelevant, wenn ein Problem auftritt, das die Auflösung des Hostnamens verlangsamt.

Warum ist hostname langsam? Ist es Reverse-DNS oder etwas Verrücktes?

In meinem System ist hostname nicht langsam, aber hostname -s ist es.

Dies könnte auf einen Grund dafür hinweisen: http://www.linuxquestions.org/questions/slackware-14/hostname-vs-hostname-s-4175592010/#post5621658

@thegreyshadow : Was passiert, wenn Sie eine weitere Zeile nur mit dem Kurznamen hinzufügen?

Dh

127.0.0.1 loli

Auf jeden Fall ist es ziemlich seltsam, dass hostname -s hier eine DNS-Suche durchführt.

@faho Ich habe es getan und es gibt keinen Unterschied. hostname -s dauert immer noch viel länger als nur hostname _OR_ bashs \h Escape-Sequenz.

@thegreyshadow : Können Sie die inetutils- Version von Hostname ausprobieren?

@faho da es sich um ein so niedriges Systemdienstprogramm handelt, würde ich dies nur ungern tun. Aber ich werde es überprüfen und sehen, was passiert.

Es ist wirklich seltsam, dass hostname -s langsamer ist als nur hostname . Der Modifikator -s soll lediglich die Domain aus dem Hostnamen entfernen. Eine Operation, die der Laufzeit nicht mehr als eine Mikrosekunde hinzufügen sollte. Ich sehe keine Rechtfertigung dafür, Fisch zu ändern, um das zu umgehen, was mit dem System des OP vor sich geht. Es gibt einfache Lösungen, die Menschen in solchen Situationen verwenden können; Erstellen Sie zB ein _~/bin/hostname_-Skript, das den echten Hostnamen ohne das Flag -s aufruft.

getestet inetutils-1.9.4 lokal kompiliert

Ausgabe:

[eduardo: ~/Downloads/inetutils/inetutils-1.9.4/tests]$ ./hostname.sh 
loli
hostname: skipping tests to set host name

der Hostname erscheint schnell, aber dann das Skript (da es ein Skript ist, scheint hostname.sh etwas mehr Zeit für die Tests zu brauchen, dann druckt es den Teil skipping tests... und wird beendet.

@krader1961 Ich weiß so gut wie nichts über Netzwerkdienstprogramme (oder Systemprogrammierung für diese Angelegenheit. Ich bin nur ein n00b und ein Benutzer). Du magst Recht haben, aber Tatsache bleibt, dass dies etwas ist, das in Fischen wahrgenommen wird, aber nicht in Bash. Ich weiß nicht, wie die Bash ihre Escape-Sequenz \h implementiert, aber sie ist schneller als hostname -s .

Bash implementiert \h durch den Aufruf von gethostname() . Tatsächlich ruft es die Funktion jedoch genau einmal auf, wenn sie gestartet wird und den Wert zwischenspeichert. Beachten Sie, dass der Befehl hostname dieselbe Funktion verwenden sollte, um den Hostnamen zu erhalten. Die Bash scheint also aller Wahrscheinlichkeit nach einfach schneller zu sein, da sie den Hostnamen nur einmal abruft, wenn sie gestartet wird. Beachten Sie, dass die meisten (alle?) Eingabeaufforderungen, die wir mit fish verpacken, dieses Muster verwenden, um zu vermeiden, dass hostname mehr als einmal aufgerufen wird, da DNS-Lookups langsam sein können (von _share/functions/fish_prompt.fish_):

# Just calculate this once, to save a few cycles when displaying the prompt
if not set -q __fish_prompt_hostname
        set -g __fish_prompt_hostname (hostname|cut -d . -f 1)
end

Dann verwendet es $__fish_prompt_hostname in der Eingabeaufforderungszeichenfolge.

Dies, plus Dinge wie hostname Verhalten auf Solaris und Cygwin, all das macht für mich ein überzeugendes Argument für eine elektrische Var.

@krader1961 In net-tools 1.6x ruft hostname auch nur gethostbyname() , aber hostname-s macht viele andere Dinge und ruft viele Programme auf. Fish könnte einfach hostname anstelle von hostname -s oder Ihren Vorschlag umsetzen und $__fish_prompt_hostname .

aber hostname -s macht viele andere Dinge und ruft viele Programme auf.

Das verdient ein "WTF?" Antwort. Es fällt mir schwer zu glauben, dass das wahr ist.

Fish könnte statt hostname einfach hostname verwenden -s

Nein, denn die beiden sind nicht gleichwertig. Das -s die Domäne. Zum Beispiel auf meinem System, wo ich Folgendes eintippe hostname => macbook.skepticism.us und hostname -s => macbook .

oder implementieren Sie, was Sie vorschlagen, indem Sie $__fish_prompt_hostname festlegen.

Das ist es, was _fish_prompt.fish_ und _fish_fallback_prompt.fish_ bereits tun. Wie die meisten, aber nicht alle Beispielaufforderungen. Ich werde eine Änderung vornehmen, um die Eingabeaufforderungen zu reparieren, die jedes Mal, wenn die Eingabeaufforderung angezeigt wird, hostname ausführen.

Für den Datensatz ist die von Ihnen gewählte Eingabeaufforderung von _share/tools/web_config/sample_prompts/user_host_path.fish_ und ist offensichtlich eine der Beispieleingabeaufforderungen, die dies langsam tun.

@krader1961

aber hostname -s macht viele andere Dinge und ruft viele Programme auf.
Das verdient ein "WTF?" Antwort. Es fällt mir schwer zu glauben, dass das wahr ist.

Nun, überprüfen Sie selbst den linuxquestions.org-Thread, den ich oben zitiert habe. Ich wünschte, ich könnte mehr zu den Vorzügen oder Mängeln davon kommentieren, aber das ganze Thema ist weit über meinem Kopf.

Für den Datensatz stammt die von Ihnen gewählte Eingabeaufforderung aus share/tools/web_config/sample_prompts/user_host_path.fish und ist offensichtlich eine der Beispieleingabeaufforderungen, die dies langsam tun.

In der Tat. Jedenfalls brauchte ich den Hostnamen nicht und zum Glück habe ich in der Funktion fish_prompt gelernt, wie man ihn loswird.

Aus diesem linuxquestions.org-Thread:

Allein durch den Vergleich der strace-Ausgabe von "hostname" und "hostname -s" passieren einige Dinge, wenn der Parameter "-s" verwendet wird, wie das Öffnen von /etc/resolv.conf, /etc/nsswitch.conf, /etc /host.conf, /etc/hosts und eine Handvoll Bibliotheksaufrufe. Vielleicht ist das der Grund.

Das ist im Grunde das, was es tun muss, um diesen Namen aufzulösen. Dies ist wahrscheinlich das Ergebnis einer Fehlkonfiguration. Normalerweise sollte es in der Lage sein, es allein aus /etc/hosts herauszubekommen.

Wird geschlossen, da dies behoben wurde und ich ein neues Problem geöffnet habe, um mich daran zu erinnern, alle Aufforderungen zu beheben, die wir mit Fisch verpacken.

@krader1961 Einverstanden, danke für die Hilfe und Geduld aller Mitglieder der Fischmuschel beim Verständnis und Lösen des Problems.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen