Tengo Fedora 20 y Gnome3 classic, y estoy intentando usar las ventanas de terminal CTRL/ALT/Fn. Cuando quiero editar un archivo con emacs, uso el siguiente script para que mi archivo de sugerencias se muestre automáticamente y emacs se ejecute como un trabajo en segundo plano. Esto funciona bien en el terminal sin inicio de sesión desde las aplicaciones de escritorio Gnome, pero en el terminal de inicio de sesión recibo mensajes de error: (obtenido mediante redirección con '&> e' en la ventana 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
¿Puede alguien explicarlos y decirme cómo evitarlos y utilizar el script emx (sin duda modificado) con éxito tanto en terminales de inicio de sesión como en terminales sin inicio de sesión?
Versión revisada de mi script emx. Incluí mis notas y material de depuración:
#!/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 "+---------------------------------------------------+"
Sí, ya veo, he caído en la trampa XY, preguntando a X cuando debería haberle preguntado a Y, así que aquí está Y.
Utilizo emacs mucho pero no todo el tiempo, y también tengo un archivo de sugerencias, en el que anoto cómo realizar las tareas que encuentro, y me gusta tener estas sugerencias disponibles mientras uso emacs. Intenté automatizar esto para que cada vez que inicie emacs, si las sugerencias aún no están allí, el archivo también se abra. Ese script fue mi intento de hacerlo, y estuvo bien mientras ejecutaba emacs desde una terminal sin inicio de sesión dentro de mi GUI de estilo clásico de Gnome3. Al intentarlo en una terminal de inicio de sesión con CTL/ALT/F2 se obtuvieron los mensajes de error citados.
He usado y amado Unix y Fedora Linux durante muchos años, pero obviamente todavía hay mucho más que aprender.
Respuesta1
A continuación, analizo su guión. Pero una vez hecho eso, creo que la respuesta a lapregunta que deberías haber hechoes:
- Huye
emacs --daemon
de tu.profile
. Esto crea una instancia en segundo plano de Emacs. - Ejecute
emacsclient FILENAME
para abrir un archivo en Emacs. Esto crea una nueva ventana (ya sea una ventana X11 o una ventana que usa la terminal actual). - Cargue el
EmacsHints
archivo en su archivo de inicio de Emacs: coloque(find-file "/home/Harry/emacs/EmacsHints.txt")
su.emacs
.
No podemos decir con certeza por qué aparece t: Permission denied
, ya que no publicó el script que generó este error (el script que publicó tiene un comentario en la línea 4). Pero estás creando un archivo temporal en el directorio actual; esa es una mala idea en todas las circunstancias y probablemente no funcione cuando no tiene permiso para escribir en el directorio actual.
Si necesita crear un archivo temporal, utilicemktemp
. Sin embargo, aquí los archivos temporales son una complicación innecesaria: utilice la sustitución de comandos para almacenar la salida de los comandos en una variable.
#!/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 …
Todo esto, a su vez, es tremendamente complicado: simplemente canalice la salida de grep
into wc
y el paso awk no hará nada útil.
if [ "$(ps aux | grep EmacsHints | wc -l)" = 2 ]; then …
Además, su prueba no es confiable: cuando el EmacsHints
archivo está abierto, a veces ps
devolverá una línea que contiene EmacsHints
, a veces dos: depende del tiempo de los procesos ps
y grep
. En lugar de crear uno propio (que no funciona), utilice herramientas dedicadas a este propósito:pidof
opgrep
.
#!/bin/sh
if pgrep -f 'EmacsHints\.txt' >/dev/null; then …
¡Voilá! Más simple y realmente funciona.
Así queprincipalmenteobras. Si abre el EmacsHints
archivo en Emacs sin especificarlo en la línea de comando, esto no será detectado. Ofrecería una solución mejor, pero no entiendo lo que estás tratando de lograr. Si siempre desea tener el EmacsHints
archivo abierto en Emacs, ábralo desde su archivo .emacs
.
Emacs tarda un poco en iniciarse, pero muchos usuarios (incluyéndome a mí) lo configuran para que se ejecute cuando inicias sesión y luego nunca sales. Huye emacs --daemon
de tu .profile
. Para abrir un archivo en la instancia de Emacs existente, llame a emacsclient
.
Con respecto a "la entrada estándar no es un tty", puede ejecutar Emacs en segundo plano solo si abre una ventana GUI. Si está ejecutando Emacs en la terminal, debe estar en primer plano; de lo contrario, no podrá acceder a la terminal. Si desea ejecutar Emacs en segundo plano sólo en X:
if [ -n "$DISPLAY" ]; then
emacs "$1" &
else
emacs "$1"
fi
Por cierto, en un script de shell, siempre coloque comillas dobles alrededor de las sustituciones de variables y comandos: "$1"
, "$foo"
, "$(somecommand)"
, etc. Cuando la sustitución no está entre comillas dobles, el valor no se interpreta como una cadena sino como una lista de patrones globales. Este problema normalmente se manifiesta con scripts que fallan en nombres de archivos que contienen espacios. Si no comprende lo que significa todo esto, utilice comillas dobles.
O simplemente podrías usar emacsclient
.
Respuesta2
Respecto a este mensaje:
emx: line 4: t: permission denied
El primero te dice que tu comando:
ps aux | grep EmacsHints > t
no tiene permisos para escribir el archivo t
en cualquier directorio en el que se encuentre cuando se ejecuta. Es mejor especificar una ruta completa, sugeriría usar /tmp/t
así:
ps aux | grep EmacsHints > /tmp/t
El otro mensaje:
emacs: standard input is not a tty
Le indica que el script no tiene acceso a un TTY para mostrar emacs. Para ejecutar una herramienta como emacs
o vim
de esta manera, a menudo necesitará tener acceso a un dispositivo TTY para poder acceder a su STDIN y STDOUT.
Si estás desesperado o no te importa la falta de STDIN/STDOUT, puedes crear uno nuevo dentro de tu script de esta manera:
emacs < $(tty) > $(tty)
Hay otros métodos para solucionar este problema; consulte estas preguntas y respuestas de SO tituladas:¿Cómo inicio un editor desde un script de shell?.