Warum kann ich plötzlich nicht mehr auf meinen Befehlszeilenverlauf zugreifen?

Warum kann ich plötzlich nicht mehr auf meinen Befehlszeilenverlauf zugreifen?

Ich verwende ksh(Version: sh (AT&T Research) 2020.0.0) unter Ubuntu 20.04 und verwende den vi-Befehlszeilenbearbeitungsmodus ( set -o vi). Das hat jahrelang gut funktioniert, aber in letzter Zeit sind mir einige Merkwürdigkeiten aufgefallen, und heute Morgen hat es schließlich ganz aufgehört zu funktionieren.

  • ~/.sh_histfileIch sehe, dass seit heute Morgen keine Befehle mehr gespeichert werden
  • Alle von mir eingegebenen Befehle konnte ich bisher durch ein Hochscrollen mit Esckoder zB. eine Suche mit finden Esc/.
  • Vor einiger Zeit schien sich dies dahingehend geändert zu haben, dass nur noch erfolgreiche Befehle gespeichert werden (was lästig ist).

Ich habe gestern keine Änderungen an meiner Konfiguration vorgenommen (glaube ich), aber der Befehlszeilenverlauf funktioniert für den Root-Benutzer.

Die Berechtigungen ~/.sh_histfileliegen bei 600 und HISTFILEsind weder für meinen normalen Benutzer noch für Root festgelegt.

Irgendeine Idee, was schiefgelaufen ist – und natürlich, wie man es behebt? Idealerweise möchte ich zu der Situation zurückkehren, in der alles, was ich in der Befehlszeile geschrieben und fertiggestellt habe, Enterin gespeichert wird ~/.sh_histfile.

Bearbeiten

Die folgenden Variablen werden gesetzt:

$ set
_=export
COMP_CWORD=0
COMP_KEY=0
COMP_POINT=0
COMP_TYPE=0
COMP_WORDBREAKS=$'"\'@><=;|&(:'
DBUS_SESSION_BUS_ADDRESS='unix:path=/run/user/1000/bus'
DISPLAY=localhost:11.0
ENV=/home/jan.andersen/.kshrc
FCEDIT=/usr/bin/ex
HISTCMD=1
HOME=/home/jan.andersen
IFS=$' \t\n'
JOBMAX=0
KSH_VERSION=.sh.version
LANG=en_US.UTF-8
LESS=X
LINENO=1
LOGNAME=jan.andersen
MAILCHECK=600
MOTD_SHOWN=pam
OLDPWD=/home/jan.andersen
OPTIND=1
PATH=/home/jan.andersen/.local/bin:/usr/local/glassfish5/bin:/usr/local/glassfish5/glassfish/bin:/usr/local/texlive/2019/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
PPID=3887
PS1=$'\'$ \''
PS2='> '
PS3='#? '
PS4='+ '
PWD=/home/jan.andersen
RANDOM=18082
SECONDS=17131.589
SHELL=/usr/bin/ksh
SHLVL=1
SH_OPTIONS=astbin=/opt/ast/bin
SSH_TTY=/dev/pts/1
TERM=xterm-256color
TMOUT=0
USER=jan.andersen
XDG_RUNTIME_DIR=/run/user/1000
XDG_SESSION_CLASS=user
XDG_SESSION_ID=10
XDG_SESSION_TYPE=tty

Das lokale Profil enthält nur Standardinhalte und am Ende ein paar Zeilen, die ich hinzugefügt habe:

$ cat .profile
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi

#eval $(ssh-agent -s)
#ssh-add ~/.ssh/id_rsa
export SSH_AUTH_SOCK=${XDG_RUNTIME_DIR}/ssh-agent.socket

Antwort1

Das istnicht verifiziertdurch andere Quellen, sondern lediglich ein Blick auf den Fall.

NB! Dies bezieht sich auf ksh-2020.

Es gibt einen Fehler bei der Handhabung des Verlaufs, wenn der Verlauf eine bestimmte Größe (Bytes) überschreitet. Dies äußert sich darin, dass die Verlaufslänge 1 (also null) beträgt und dort bleibt. Wenn das Limit erreicht wird, wird der Fehler beim kshnächsten Durchlauf ausgelöst.

Verwenden Sie etwas wie:

PS1='$_pwd [!]\$ '

zeigt Pfad + Anzahl der Verlaufseinträge.

Bei einem normalen Laufsh_histinitwird beim Start aufgerufen. Aus einem Grund, der nicht ermittelt werden kann, wird diese Funktion aufgerufenfür jeden Befehlwenn dieser Fehler aktiv ist. Weiterehist_writewird normalerweise aufgerufen, um den Datensatz zu schreiben, wird aber nicht aufgerufen, wenn der Fehler aktiv ist.

Als Ergebnis erhält manein neuer Dateideskriptorzu .sh_hisoryfürjeder Befehl. Dies ist wahrscheinlich das, was Sie auch /proc/PID/fdin den Kommentaren gesehen haben. Weitere Befehle werden nicht in die Datei geschrieben.

Die Lösung besteht zumindest hier darin, den alten Verlauf zu archivieren und einen neuen zu beginnen. Wahrscheinlich ist es ratsam, die Shell neu zu starten.

Ohne HISTSIZEDefinition ist die Grenze, ab der der Fehler ausgelöst wird, gering. Ein paar hundert Datensätze. Sie können eine große Zahl wie 50000 festlegen, um ihn zu „verzögern“. In meinen Tests wurde er dann bei etwa 32.000 Zeilen mit einer Größe von 50000 ausgelöst. Ich habe die Größe auf 500000 erhöht und dann funktionierte es wieder wie erwartet.

ksh93Wie erwähnt ist es wahrscheinlich auch ratsam , anstelle der Version 2020 zu installieren . So wie es aussieht, ist die Version 2020 ins Stocken geraten. ( 93bedeutet nicht, dass sie aus dem Jahr 1993 ist – basiert aber auf dieser Version. Wahrscheinlich 93u)

Die 93uVersion hat diesen Fehler nicht.

Wenn /etc/skel/.kshrckeine Quelle vorhanden ist, möchten Sie diese Datei wahrscheinlich auch in Ihr Home-Verzeichnis kopieren. EswahrscheinlichSie haben bereits einen HISTSIZESatz, ändern Sie diesen in einen großen Wert, wenn Sie mit der Version 2020 fortfahren.



Ursprünglicher „Kommentar“

Das ist zu lang für einen Kommentar, deshalb schreibe ich es als „Antwort“. (Unter der Annahme von Linux)

Einen Hinweis darauf, was los ist, finden Sie möglicherweise durch:


Führen Sie es normal in einem Terminal aus ksh. Holen Sie sich die PID dieser Shell.

Überprüfen Sie /proc/PID/fd/. Es sollte in der Regel offene fd 3 haben, um/home/username/.sh_history

Geben Sie in der zweiten Shell ein strace -p PID. Wenn Sie in der ersten Shell eingeben, ksollten Sie in der ausgeführten Shell normalerweise so etwas sehen strace.

Lesen Sie die Geschichte von k:

select(1, [0], NULL, NULL, NULL)        = 1 (in [0])
recvfrom(0, 0x7ffdcff6c0d0, 80, MSG_PEEK, NULL, NULL) = -1 ENOTSOCK (Socket operation on non-socket)
read(0, "k", 80)                        = 1
lseek(3, 0, SEEK_SET)                   = 0
lseek(3, 0, SEEK_SET)                   = 0
read(3, "\201\1[ --help\n\0exit\n\0env\n\0\0ls\n\0q\n\0\0"..., 65536) = 258
lseek(3, 0, SEEK_END)                   = 258
write(2, "man foo\10\10\10\10\10\10\10", 14) = 14

Hier:

read(0, "k", 80) = 1 von STDIN lesen, 1 Byte lesen, „k“ (Der eingegebene Schlüssel)
read(3, "\201\1[ ... 65536 Bytes von fd 3 gelesen, Verlaufsdatei lesen. write(2, "man foo... schreibenman foo, der vorherige Befehl wird angezeigt.

Geschichte schreiben:

Geben Sie in der ersten Shell einen Befehl ein. Im folgenden Protokoll habe ich cd ircFolgendes eingegeben:~/tmp

Ausschnitt ausEingabec<Enter>

write(2, "c", 1)                        = 1
select(1, [0], NULL, NULL, NULL)        = 1 (in [0])
recvfrom(0, 0x7ffdcff6c0d0, 80, MSG_PEEK, NULL, NULL) = -1 ENOTSOCK (Socket operation on non-socket)
read(0, "\r", 80)                       = 1
ioctl(2, TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0
ioctl(2, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(2, "\n", 1)                       = 1
lseek(3, 0, SEEK_END)                   = 270
lseek(3, 0, SEEK_CUR)                   = 270
lseek(3, 270, SEEK_SET)                 = 270
read(3, "", 65536)                      = 0
lseek(3, 0, SEEK_END)                   = 270
lseek(3, 0, SEEK_END)                   = 270
write(3, "cd irc\n\0", 8)               = 8
lseek(3, 0, SEEK_CUR)                   = 278
chdir("irc")                            = 0
lseek(3, 0, SEEK_END)                   = 278
lseek(3, 278, SEEK_SET)                 = 278
lseek(3, 278, SEEK_SET)                 = 278
read(3, "", 65536)                      = 0
write(2, "~/tmp/irc [36]$ ", 16)        = 16

Hier das:
write(3, "cd irc\n\0", 8) = 8

ist die Zeile, die in die Verlaufsdatei schreibt.

verwandte Informationen