У меня 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 под названием:Как запустить редактор из скрипта оболочки?.