„emacs: Standardeingabe ist kein TTY“ beim Starten von Emacs bei der Anmeldung

„emacs: Standardeingabe ist kein TTY“ beim Starten von Emacs bei der Anmeldung

Ich habe Fedora 20 und Gnome3 Classic und versuche, die CTRL/ALT/Fn-Terminalfenster zu verwenden. Wenn ich eine Datei mit Emacs bearbeiten möchte, verwende ich das folgende Skript, damit meine Hints-Datei automatisch angezeigt wird und Emacs als Hintergrundjob ausgeführt wird. Dies funktioniert im Nicht-Login-Terminal von Gnome-Desktopanwendungen aus einwandfrei, aber im Login-Terminal erhalte ich Fehlermeldungen: (erhalten durch Umleitung mit „&> e“ im CTL/ALT/F2-Fenster)

    home/Harry/bin/emx: line 4: t: Permission denied  
    +---------------------------------------------------+  
    | EmacsHints.txt found and displayed                |  
    | Usage: ./emx <filename> ..                        |  
    |   .. Opens EmacsHints.txt and <filename> in emacs |  
    +---------------------------------------------------+
    emacs: standard input is not a tty

Kann mir das bitte jemand erklären und mir sagen, wie ich es vermeiden und das (zweifellos modifizierte) EMX-Skript sowohl in Terminals mit als auch ohne Anmeldung erfolgreich verwenden kann?

Überarbeitete Version meines EMX-Skripts, ich habe meine Notizen und Debugging-Materialien beigefügt:

#!/bin/sh
emxhn="EmacsHints.txt"
emxhf="/home/Harry/emacs/$emxhn"
ps aux | grep $emxhn > t
T=`wc -l t` # no spaces allowed between T and = and value
# echo $T
wc -l t > t1
T=`awk '$1' t1`
# echo $T

echo "+---------------------------------------------------+"

# In the test "" needed round $T else it is split into two commands ..
# .. so are the spaces after [ and before ]
# could be if ( [...] ) then or if [...] ; then 
if [ "$T" = "2 t" ]; then 
#  echo "+----------------------------------------------+"
 echo "| $emxhn already present"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  "|"
else
 emacs $emxhf &
 echo "| $emxhn found and displayed"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \  "|"
fi

if [ "$#" = "1" ]; then
 emacs $1 &
else
 echo "| Usage: ./emx <filename> .." \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  "|"
 echo "|" \   ".. Opens $emxhn and <filename> in emacs" "|"
fi

  echo "+---------------------------------------------------+"

Ja, ich sehe, ich bin in die XY-Falle getappt und habe X gefragt, obwohl ich Y hätte fragen sollen, also hier ist Y

Ich verwende Emacs häufig, aber nicht ständig, und ich habe auch eine Datei mit Hinweisen, in der ich festhalte, wie ich die anfallenden Aufgaben erledige. Ich möchte diese Hinweise gerne zur Verfügung haben, während ich Emacs verwende. Ich habe versucht, dies zu automatisieren, sodass die Datei immer dann geöffnet wird, wenn ich Emacs starte und die Hinweise noch nicht vorhanden sind. Dieses Skript war mein Versuch, dies zu tun, und es hat funktioniert, während ich Emacs von einem Nicht-Anmeldeterminal innerhalb meiner klassischen Gnome3-GUI ausgeführt habe. Der Versuch in einem Anmeldeterminal mit CTL/ALT/F2 ergab die zitierten Fehlermeldungen.

Ich verwende und liebe Unix und Fedora Linux seit vielen Jahren, aber es gibt offensichtlich noch eine ganze Menge mehr zu lernen.

Antwort1

Im Folgenden analysiere ich Ihr Skript. Aber nachdem ich das getan habe, denke ich, die Antwort auf dieFrage, die Sie hätten stellen sollenIst:

  • Führen Sie es emacs --daemonvon Ihrem .profileaus. Dadurch wird eine Hintergrundinstanz von Emacs erstellt.
  • Ausführen emacsclient FILENAME, um eine Datei in Emacs zu öffnen. Dadurch wird ein neues Fenster erstellt (entweder ein X11-Fenster oder ein Fenster, das das aktuelle Terminal verwendet).
  • Laden Sie die EmacsHintsDatei in Ihre Emacs-Startdatei: Fügen Sie sie (find-file "/home/Harry/emacs/EmacsHints.txt")in Ihre ein .emacs.

Wir können nicht mit Sicherheit sagen, warum Sie erhalten t: Permission denied, da Sie das Skript, das diesen Fehler erzeugt hat, nicht gepostet haben (das von Ihnen gepostete Skript hat einen Kommentar in Zeile 4). Aber Sie erstellen eine temporäre Datei im aktuellen Verzeichnis; das ist unter allen Umständen eine schlechte Idee und funktioniert wahrscheinlich nicht, wenn Sie keine Schreibberechtigung für das aktuelle Verzeichnis haben.

Wenn Sie eine temporäre Datei erstellen müssen, verwenden Siemktemp. Allerdings stellen temporäre Dateien hier eine unnötige Komplikation dar: Verwenden Sie Befehlsersetzung, um die Ausgabe der Befehle in einer Variablen zu speichern.

#!/bin/sh
ps_lines=$(ps aux | grep EmacsHints)
line_count=$(echo "$ps_lines" | wc -l)
T=$(echo "$line_count" | awk '$1')
if [ "$T" = "2" ]; then …

Dies alles wiederum ist furchtbar kompliziert – leiten Sie die Ausgabe von einfach grepin weiter wc, und der awk-Schritt bewirkt nichts Nützliches.

if [ "$(ps aux | grep EmacsHints | wc -l)" = 2 ]; then …

Darüber hinaus ist Ihr Test unzuverlässig: Wenn die EmacsHintsDatei geöffnet ist, pswird manchmal eine Zeile mit zurückgegeben EmacsHints, manchmal zwei: Dies hängt vom Timing der Prozesse psund ab grep. Anstatt Ihren eigenen Test zu erstellen (was nicht funktioniert), verwenden Sie Tools, die speziell für diesen Zweck entwickelt wurden:pidofoderpgrep.

#!/bin/sh
if pgrep -f 'EmacsHints\.txt' >/dev/null; then …

Voilà! Einfacher, und es funktioniert tatsächlich.

Nun, esmeistensfunktioniert. Wenn Sie die EmacsHintsDatei in Emacs öffnen, ohne sie in der Befehlszeile anzugeben, wird dies nicht erkannt. Ich würde eine bessere Lösung anbieten, aber ich verstehe nicht, was Sie erreichen möchten. Wenn Sie die EmacsHintsDatei immer in Emacs geöffnet haben möchten, öffnen Sie sie von Ihrem .emacs.

Emacs startet etwas langsam, aber viele Benutzer (mich eingeschlossen) richten es so ein, dass es nach der Anmeldung ausgeführt wird und dann nicht mehr beendet wird. Führen Sie es emacs --daemonvon Ihrem .profileaus aus. Um eine Datei in der vorhandenen Emacs-Instanz zu öffnen, rufen Sie auf emacsclient.

Bezüglich „Standardeingabe ist kein TTY“ können Sie Emacs nur dann im Hintergrund laufen lassen, wenn es ein GUI-Fenster öffnet. Wenn Sie Emacs im Terminal laufen lassen, muss es im Vordergrund sein, sonst kann es nicht auf das Terminal zugreifen. Wenn Sie Emacs nur unter X im Hintergrund laufen lassen wollen:

if [ -n "$DISPLAY" ]; then
  emacs "$1" &
else
  emacs "$1"
fi

Übrigens sollten Sie in einem Shell-Skript Variablen- und Befehlsersetzungen immer in Anführungszeichen setzen: "$1", "$foo", "$(somecommand)", usw. Wenn die Ersetzung nicht in Anführungszeichen steht, wird der Wert nicht als Zeichenfolge, sondern als Liste von Glob-Mustern interpretiert. Dieses Problem tritt normalerweise bei Skripten auf, die bei Dateinamen mit Leerzeichen fehlschlagen. Wenn Sie nicht verstehen, was das alles bedeutet, verwenden Sie einfach Anführungszeichen.

Oder Sie verwenden einfach emacsclient.

Antwort2

Zu dieser Nachricht:

emx: line 4: t: permission denied

Die erste besteht darin, Ihnen mitzuteilen, dass Ihr Befehl:

ps aux | grep EmacsHints > t

hat keine Berechtigung, die Datei tin das Verzeichnis zu schreiben, in dem sie sich beim Ausführen befindet. Es ist besser, einen vollständigen Pfad anzugeben. Ich würde /tmp/tFolgendes vorschlagen:

ps aux | grep EmacsHints > /tmp/t

Die andere Nachricht:

emacs: standard input is not a tty

Sagt Ihnen, dass das Skript keinen Zugriff auf ein TTY hat, um Emacs anzuzeigen. Um ein Tool wie emacsoder vimauf diese Weise auszuführen, müssen Sie häufig Zugriff auf ein TTY-Gerät haben, damit Sie auf dessen STDIN und STDOUT zugreifen können.

Wenn Sie verzweifelt sind oder das Fehlen von STDIN/STDOUT Ihnen egal ist, können Sie in Ihrem Skript wie folgt ein neues erstellen:

emacs < $(tty) > $(tty)

Es gibt andere Methoden, damit umzugehen, siehe diese SO-Fragen und -Antworten mit dem Titel:Wie starte ich einen Editor aus einem Shell-Skript?.

verwandte Informationen