«emacs: стандартный ввод не является tty» при запуске Emacs при входе в систему

«emacs: стандартный ввод не является tty» при запуске Emacs при входе в систему

У меня Fedora 20 и Gnome3 classic, и я пытаюсь использовать окна терминала CTRL/ALT/Fn. Когда я хочу редактировать файл с помощью emacs, я использую следующий скрипт, чтобы мой файл Hints автоматически отображался, а emacs запускался как фоновое задание. Это отлично работает в терминале без входа в систему из приложений рабочего стола Gnome, но в терминале входа в систему я получаю сообщения об ошибках: (получено путем перенаправления с помощью '&> e' в окне CTL/ALT/F2)

    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

Может ли кто-нибудь объяснить это и подсказать, как их избежать и успешно использовать скрипт emx (несомненно, модифицированный) как в терминалах с входом в систему, так и в терминалах без входа в систему?

Исправленная версия моего emx-скрипта, в которую я включил свои заметки и отладочные материалы:

#!/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 "+---------------------------------------------------+"

Да, понятно, я попал в ловушку XY, спрашивая X, когда мне следовало спросить Y, так что вот Y

Я часто использую emacs, но не постоянно, и у меня также есть файл Hints, в котором я отмечаю, как выполнять задачи, с которыми я сталкиваюсь, и мне нравится иметь эти Hints доступными, пока я использую emacs. Я попытался автоматизировать это так, чтобы всякий раз, когда я запускаю emacs, если Hints еще нет, то файл также открывался. Этот скрипт был моей попыткой сделать это, и он был в порядке, пока я запускал emacs из терминала без входа в систему в моем классическом стиле Gnome3 GUI. Попытка использовать его в терминале входа с CTL/ALT/F2 дала приведенные сообщения об ошибках.

Я много лет использую и люблю Unix и Fedora Linux, но, очевидно, мне еще очень многому предстоит научиться.

решение1

Ниже я анализирую ваш сценарий. Но сделав это, я думаю, что ответ навопрос, который вы должны были задатьявляется:

  • Запустите emacs --daemonиз вашего .profile. Это создаст фоновый экземпляр Emacs.
  • Запустите emacsclient FILENAME, чтобы открыть файл в Emacs. Это создаст новое окно (либо окно X11, либо окно, использующее текущий терминал).
  • Загрузите EmacsHintsфайл в файл запуска Emacs: поместите (find-file "/home/Harry/emacs/EmacsHints.txt")туда ваш .emacs.

Мы не можем точно сказать, почему вы получаете t: Permission denied, поскольку вы не опубликовали скрипт, который сгенерировал эту ошибку (в опубликованном вами скрипте есть комментарий на строке 4). Но вы создаете временный файл в текущем каталоге; это плохая идея при любых обстоятельствах, и, вероятно, не работает, когда у вас нет разрешения на запись в текущий каталог.

Если вам нужно создать временный файл, используйтеmktemp. Однако здесь временные файлы являются ненужным усложнением: используйте подстановку команд, чтобы сохранить вывод команд в переменной.

#!/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 …

Все это, в свою очередь, ужасно сложно — просто передайте вывод grepв wc, и этап awk не сделает ничего полезного.

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

Более того, ваш тест ненадежен: когда файл EmacsHintsоткрыт, иногда psон возвращает одну строку, содержащую EmacsHints, иногда две: это зависит от времени выполнения процессов psи grep. Вместо того, чтобы создавать свой собственный (который не работает), используйте инструменты, предназначенные для этой цели:pidofилиpgrep.

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

Вуаля! Проще и на самом деле работает.

Ну, этопо большей частиработает. Если вы откроете EmacsHintsфайл в Emacs, не указав его в командной строке, это не будет обнаружено. Я бы предложил лучшее решение, но я не понимаю, чего вы пытаетесь добиться. Если вы всегда хотите, чтобы файл EmacsHintsбыл открыт в Emacs, откройте его из вашего .emacs.

Emacs немного медленно запускается, но многие пользователи (включая меня) настраивают его на запуск при входе в систему и никогда не выходят из него. Запустите emacs --daemonиз вашего .profile. Чтобы открыть файл в существующем экземпляре Emacs, вызовите emacsclient.

Что касается «стандартного ввода — это не tty», вы можете запустить Emacs в фоновом режиме, только если он открывает окно GUI. Если вы запускаете Emacs в терминале, он должен быть на переднем плане, иначе он не сможет получить доступ к терминалу. Если вы хотите запустить Emacs в фоновом режиме только в X:

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

Кстати, в скрипте оболочки всегда заключайте в двойные кавычки подстановки переменных и команд: "$1", "$foo", "$(somecommand)", и т. д. Если подстановка не заключена в двойные кавычки, значение интерпретируется не как строка, а как список шаблонов glob. Эта проблема обычно проявляется в скриптах, которые не срабатывают на именах файлов, содержащих пробелы. Если вы не понимаете, что все это значит, просто используйте двойные кавычки.

Или вы можете просто использовать emacsclient.

решение2

По поводу этого сообщения:

emx: line 4: t: permission denied

Первая сообщает вам, что ваша команда:

ps aux | grep EmacsHints > t

не имеет прав на запись файла tв любой каталог, в котором он находится при запуске. Лучше указать полный путь, я бы предложил использовать /tmp/tтак:

ps aux | grep EmacsHints > /tmp/t

Другое сообщение:

emacs: standard input is not a tty

Говорит вам, что скрипт не имеет доступа к TTY для отображения emacs. Чтобы запустить такой инструмент, как emacsили vimтаким образом, вам часто понадобится доступ к устройству TTY, чтобы вы могли получить доступ к его STDIN и STDOUT.

Если вы в отчаянии или вас не волнует отсутствие STDIN/STDOUT, вы можете создать новый в своем скрипте следующим образом:

emacs < $(tty) > $(tty)

Существуют и другие методы решения этой проблемы, см. этот SO Q&A под названием:Как запустить редактор из скрипта оболочки?.

Связанный контент