Verhindern Sie, dass das Terminal zuvor ausgeführte Befehle anzeigt

7

Ich habe ein Skript, mit dem ich zufällige Gedanken protokollieren kann, während ich an einem Projekt arbeite. Im Terminal würde ich durch Ausführen einen neuen Protokolleintrag hinzufügen

$ @ "some random thought"

Wo @ist nur ein Alias ​​für mein Skript.

Angenommen, mein Terminal befindet sich in diesem Zustand:

$ ls /var/tmp
somefile.ext
another-file.l
$ _

Nach dem Ausführen meines Skripts würde es folgendermaßen aussehen:

$ ls /var/tmp
somefile.ext
another-file.l
$ @ "some random thought"
$ _

Jetzt möchte ich nicht, dass diese Zeile ( $ @ "some random thought") auf dem Bildschirm bleibt, nachdem ich sie eingegeben habe. Ich möchte nur, dass das Skript ausgeführt wird und keine Spuren auf dem Bildschirm hinterlassen (einige Dinge sind persönlich und andere sehen möglicherweise mein Terminal). Ich möchte auch nicht clearden gesamten Bildschirm.

Halten Sie das für möglich? Ich benutze Iterm2, wenn dies hilft.

NB: Ich weiß, wie ich damit umgehen soll history, damit meine Protokolleinträge nicht aufgezeichnet werden. Ich möchte nur keine Spur auf dem Bildschirm hinterlassen.

whonoes
quelle
Da ich auf @mutzmatron antwortete, würde dies in meinem Fall nicht helfen.
Whonoes
Ja, das habe ich gerade auch bemerkt.
Risto Salminen
Ich bezweifle, dass es eine einfache Möglichkeit gibt, die letzte Zeile des Terminals zu löschen. Die einfachste Lösung wäre wahrscheinlich das Schreiben einer eigenen Shell.
Risto Salminen

Antworten:

4

Sie können versuchen, die vorherige Zeile zu überschreiben, die bereits beantwortet wurde.

Wie kann man den Inhalt einer Zeile auf dem Terminal ändern, anstatt eine neue zu schreiben?

Zum Beispiel (geändert von der ursprünglichen Antwort):

prompt% echo -n "Old line"; echo "\033[1A\033[1A" "new line"

Wird nur angezeigt:

prompt% new line

Als Ausgabe. Durch Hinzufügen weiterer \ 033 [1A-Sequenzen werden mehr Zeilen entfernt.

Vorsichtsmaßnahme : Dies funktioniert nicht auf allen Terminals.

jmetz
quelle
Mein Skript gibt nichts aus. Ich möchte den eigentlichen Befehl vom Bildschirm entfernen, nicht seine Ausgabe.
Whonoes
Ja, dadurch wird die letzte Skriptausgabezeile überschrieben . Mit Ihrem Beispiel möchte prompt% echo -n "Old line"; echo -e "\e[0K\r new line"ich aus dem Terminal verschwinden.
Whonoes
Sie haben Recht, ich habe meine Antwort mit der richtigen Terminalsequenz aktualisiert.
jmetz
1
Danke Mutzmatron, das löst mein Problem. Eine Einschränkung wäre, dass nur die letzte gelöscht wird, wenn die Zeichenfolge, die ich an das Skript übergebe, mehr als eine Zeile enthält (der Text wird im Terminal umbrochen). Das Hinzufügen weiterer \ 033 [1A-Sequenzen würde funktionieren, aber wenn ich dann eine Zeichenfolge mit nur einer Zeile hinzufüge, werden mehr als eine Zeile aus dem Terminal entfernt. Trotzdem, gut genug für meinen Fall, werde ich Ihre Antwort akzeptieren, danke!
Whonoes
1
Ich habe gerade die Antwort gepostet, die ich komponiert habe, und du hast mich geschlagen. Meine eigene Lösung verwendet tputkeine Terminalanweisungen, daher ist sie über Terminals hinweg portabler. Es funktioniert auch mit mehrzeiliger Ausgabe - aber es bricht ab, wenn die Ausgabe viel scrollt.
Alexios
7

Anstatt einen Befehl zur Eingabe Ihres Gedankens zu haben, können Sie dafür ein Widget definieren. In zsh:

thought() { 
  print -r -- $BUFFER >> ~/.thoughts
  # or: your-script $BUFFER
  BUFFER=
  zle -M 'thought recorded'
}
zle -N thought
bindkey '^T' thought

Drücken Sie dann Ctrl-T, um den Inhalt des Puffers zu Ihrer ~/.thoughtsDatei hinzuzufügen, und löschen Sie ihn anschließend ( BUFFER=). Dann müssen Sie sich keine Gedanken mehr über das Zitieren machen.

Ein anderer Ansatz könnte darin bestehen, interaktive Kommentare zu verwenden:

setopt interactive_comments
alias '@=:;#'
preexec() {
  [[ $1 = @* ]] && {
    print -r -- ${1#* } >> ~/.thoughts
    # or: your-script ${1#* }
    echoti cuu1
  }
}

Auch hier kein Problem mit Zitieren, aber das funktioniert nur für einzeilige Gedanken. (Der echoti cuu1sorgt dafür, dass diese Zeile durch Bewegen des Cursors nach oben gelöscht wird.)

Stéphane Chazelas
quelle
Umgeht dies nicht die Frage ...?
Jmetz
Danke Stephane, aber ich habe bereits ein funktionierendes Skript (Python), das etwas mehr kann als nur Zeichenfolgen zu protokollieren. Ihre Lösung bedeutet, dass ich alles wegwerfen muss und es ist ein bisschen kompliziert für meinen einfachen Fall :) Mutzmatrons Antwort hat mein Problem gelöst.
Whonoes
Ich habe diese Antwort nach dem Posten meiner Antwort positiv bewertet, weil ich denke, dass sie weniger klobig ist als ein Terminal-Hack. Aber es gibt keine Erklärung für den Geschmack!
Alexios
@whonoes, füge einfach einen Aufruf zu "your-script" hinzu, das print >> ~/.thoughtswar nur ein Beispiel, damit jeder es testen kann.
Stéphane Chazelas
@stephane, dies ist in der Tat eine elegantere Lösung; Ich möchte einfach alles in meinem Skript lösen (was zu einfach ist, um ein Widget als Abhängigkeit zu haben, wenn ich das vermeiden kann, selbst wenn ich einen Terminal-Hack verwende)
whonoes
6

Achtung, dies ist ein schrecklicher, schrecklicher Hack (aber dann ist die gesamte Anfrage ein bisschen ein Hack). :) :)

Hier ist etwas, das auf den meisten Terminals funktioniert , einschließlich des Braindead-MS-DOS-Emulators 'ANSI.SYS'. Funktioniert natürlich nicht an dummen Terminals (aber nichts wird es tun):

tput sc
echo "This will be hidden."
sleep 5
tput rc; tput cuu 1; tput ed

Dies ist offensichtlich ein Beispiel. Befreien Sie sich von echound sleepund ersetzen Sie es durch Ihren Befehl. So funktioniert das:

  • tput sc speichert die aktuellen Koordinaten des Cursors auf dem Bildschirm,
  • tput rcBewegt den Cursor zurück zu den gespeicherten Koordinaten. Möglicherweise wurde der Bildschirm gescrollt, sodass sich das vertrauliche Material in der Zeile über dem gespeicherten befindet. Damit,
  • tput cuu 1bewegt den Cursor eine Zeile nach oben. (Wenn Sie sich besonders paranoid fühlen, können Sie die Anzahl erhöhen.
  • Zum Schluss wird tput edbis zum Ende des Bildschirms gelöscht (dh vom Cursor bis zum Zeilenende und dann vom Cursor bis zum unteren Bildschirmrand).

Dies scschlägt komisch fehl, wenn der Bildschirm viel scrollt, weil Sie nichts über das Scrollen wissen, sondern nur die Bildschirmkoordinaten.

tputist terminalunabhängig, funktioniert also, solange Ihr bestimmtes Terminal in der terminfo-Datenbank aufgeführt und die TERMVariable korrekt eingestellt ist.

Alexios
quelle
Upvoted für Portabilität - funktioniert in der Tat großartig!
Whonoes
0

Nun, wenn es sich nur some random thoughtum einen tatsächlichen Befehl handelt, können Sie dies tun, indem Sie spacevor dem Befehl hinzufügen thought. Dieser Befehl wird vom Eintritt in die Geschichte ausgeschlossen

satish@Satish:/tmp $ echo "I'm in history"
I'm in history
satish@Satish:/tmp $  echo "I'm not"
I'm not
satish@Satish:/tmp $ history | tail -n 3
 1887  sudo su -
 1888  echo "I'm in history"
 1889  history | tail -n 3
satish@Satish:/tmp $ 
SHW
quelle
2
Das OP möchte, dass der Befehl nicht im Terminal vorhanden ist, nicht im Verlauf.
Jmetz
Wie in der Frage erwähnt, ist die Geschichte kein Problem, das kann ich schaffen. In Ihrem Beispiel möchte ich, dass diese Zeile satish@Satish:/tmp $ echo "I'm not"nach dem Ausführen vor dem Terminal ausgeblendet wird .
Whonoes
Ja ... ich habe es verstanden ... werde sehen, ob ich eine Lösung dafür finden kann. Und dann werde ich hier posten :)
SHW