¿Cómo iniciar un terminal con cierto texto ya ingresado en la línea de comandos?

25

En lugar de reformular mi pregunta, permítame describirle el caso de usuario deseado:

Creo un script de shell corto para ejecutar el comando "gnome-terminal --someoptionflagname 'mi texto que se publicará'", y ejecuto este script.

Aparece el terminal Gnome, con la línea de comandos seguida de mi texto.

es decir: fields@mycomputer:/$ my text to be posted

Se puede hacer esto?

emf
fuente
Si este error se fija siempre en Ubuntu usted debe buscar en cnee .
ændrük
@ ændrük Está arreglado y el nombre del paquete xneeahora.
postre

Respuestas:

32

Puede hacer esto con esperar ( instalar ). Crear y hacer ejecutable ~/bin/myprompt:

#!/usr/bin/expect -f

# Get a Bash shell
spawn -noecho bash

# Wait for a prompt
expect "$ "

# Type something
send "my text to be posted"

# Hand over control to the user
interact

exit

y ejecute Gnome Terminal con:

gnome-terminal -e ~/bin/myprompt
ændrük
fuente
+1 por usar Expect. Lo he usado durante años para ayudar a automatizar muchas cosas.
Marco Ceppi
Esto es genial Esperaba que hubiera una respuesta simple (ish) basada en la funcionalidad predeterminada de gnome-terminal, pero parece que esto responde al trabajo.
fem
Este me ha estado molestando tanto tiempo que casi no podía recordar cuál era el caso de uso previsto. Entonces, para aclarar: me gustaría hacer algo como "gnome-terminal -e ls", pero el problema es que la ventana permanezca abierta. Entonces, básicamente atajos para abrir una terminal y ejecutar comandos de shell. ¿Esto aclara los problemas frente a las respuestas de aendruk / msw?
fem
1
Si todo lo que desea es que el terminal permanezca abierto después de un comando, existen soluciones mucho más simples .
ændrük
Súper, gracias. Lo he integrado con éxito en un script de shell que llama a la herramienta de integración de datos Pentaho. Luego agregué la llamada a este script al lanzador Unity en 11.10, y funciona de maravilla.
bioShark
8

Si entiendo correctamente, desea que su primera línea de entrada se complete previamente con el contenido que pasa en la línea de comando gnome-terminal.

No sé cómo hacer exactamente esto con bash, pero aquí hay algo que se acerca. En su ~/.bashrc, agregue la siguiente línea al final:

history -s "$BASH_INITIAL_COMMAND"

Ejecute gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bashy presione Upen el indicador para recuperar el texto.

Tenga en cuenta también que si coloca set -o historycomentarios seguidos al final de su .bashrc, se ingresarán en el historial cuando comience bash, por lo que puede usarlos como base para la edición al alcanzarlos con la Uptecla y eliminar la inicial #.

Gilles 'SO- deja de ser malvado'
fuente
2
Aunque no era la solución que estaba buscando, es interesante por derecho propio.
fem
8

La sugerencia de ændrük es muy buena y funcionó para mí, sin embargo, el comando está codificado dentro del script, y si cambia el tamaño de la ventana de terminal no funciona bien. Usando su código como base, agregué la capacidad de enviar el comando myprompt al comando como argumento, y este script maneja correctamente el cambio de tamaño de la ventana del terminal.

#!/usr/bin/expect

#trap sigwinch and pass it to the child we spawned
#this allows the gnome-terminal window to be resized
trap {
 set rows [stty rows]
 set cols [stty columns]
 stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH

set arg1 [lindex $argv 0]

# Get a Bash shell
spawn -noecho bash

# Wait for a prompt
expect "$ "

# Type something
send $arg1

# Hand over control to the user
interact

exit

y ejecute Gnome Terminal con:

gnome-terminal -e "~/bin/myprompt \"my text to be posted\""
Gordon McCreight
fuente
1

La respuesta de ændrük está bien, pero quizás sea un poco pesada para la tarea.

Aquí hay un guión que escribe un guión basado en sus argumentos

#!/bin/sh
# terminal-plus-command: start a subordinate terminal which runs
# the interactive shell after first running the command arguments

tmpscript=/tmp/tmpscript.$$
echo "#!$SHELL" > $tmpscript
echo "$@" >> $tmpscript
echo exec "$SHELL" >> $tmpscript
chmod +x $tmpscript
gnome-terminal --command $tmpscript
rm -f $tmpscript

Si no has hecho mucha programación de shell, parece que hay más magia aquí que la que hay. Primero, nombro un archivo temporal para contener el script donde $$está el ID del proceso del shell que ejecuta este script. La /tmp/something.$$metáfora se usa en caso de que dos instancias de este script se ejecuten al mismo tiempo, no intentarán usar el mismo archivo temporal.

La variable $SHELLse establece con el nombre del shell que ejecuta el script. Si usa / usr / bin / bash, presumiblemente le gustaría que el mini script también lo use.

El "$@"es un idioma de shell para "interpolar todos mis argumentos, citándolos si es necesario". Esta peculiar sintaxis provoca

script.sh 'my file' your\ file

interpolar los argumentos como dos elementos

"my file" "your file"

en lugar de los cuatro que $@producirían

"my" "file" "your" "file"

Las últimas líneas del script arreglan para que un terminal gnome comience a ejecutar el mini script y luego inicie un shell interactivo. Cuando el terminal gnome se cierra, el script temporal se elimina porque la basura no está fresca.

La última línea no es parte del mini script, demuestra que el mini script funciona. Si el script de 11 líneas anterior está en un archivo llamado, rt.shentonces lo chmodhace ejecutable y luego se ejecuta.

$ chmod +x rt.sh && ./rt.sh echo hello world

El resultado de todo esto será un terminal de gnomo que se inicia, muestra

hello world

en su primera línea y luego inicia un shell interactivo:

msw@myhost:~$
msw
fuente
Creo que su secuencia de comandos podría reducirse a gnome-terminal -x sh -c "echo hello world; bash", lo que no creo que se haga la pregunta.
ændrük
Esto se ve genial. ¿Puedes explicar lo que está pasando aquí?
fem
1
emfields: lo anoté para ti.
msw
1
usted rockea gracias por las anotaciones, este tipo de ayuda hace barrera a la entrada con las secuencias de comandos mucho más accesible
fem
0

Las dos respuestas me han gustado mejor para solucionar este están utilizando expecty éste en el que recomiendan el uso de la --init-filebandera, ya sea en el tinglado o al ejecutar el terminal:

#!/bin/bash --init-file
commands to run

... y ejecutarlo como:

xterm -e /path/to/script
# or
gnome-terminal -e /path/to/script
# or
the-terminal -e bash --init-file /path/to/script/with/no/shebang

expect es probablemente la mejor solución (por las razones que describiré), excepto que no puedo controlar si está instalado en mi entorno de destino.

El problema que encontré con bash --init-filey gnome-terminal's --commandcomo truco para resolver esto es que el shell no tiene acceso a STDIN mientras ejecuta scripts de inicio. Si, por ejemplo, quiero ejecutar algo que requiera la entrada del usuario (ftp, telnet, etc.) pero deje el shell principal ejecutándose después, no funcionará; La única excepción que he visto hasta ahora es ssh:

xterm -e /bin/bash --init-file <(echo 'ssh -X some-machine')

... pero lo que necesito es más complicado que este ejemplo de juguete. De todos modos, espero que las --init-filecosas sean útiles para cualquiera que lea esta pregunta.

Brian Vandenberg
fuente
-1

Puede usar los argumentos -eo -xpara ejecutar un comando dentro de un terminal emergente, pero eso no es exactamente lo que desea.

Karl Bielefeldt
fuente
cerca, pero no exactamente lo que estoy buscando. Un problema, para este caso, es que cuando se ejecuta y finaliza, el terminal se cerrará inmediatamente. Entonces, digamos que quiero un acceso directo a "ls ~ / notes", se cerrará antes de que pueda ver la salida.
fem
Si hubiera una solución a esto, resolvería la mayoría de los casos que estoy buscando.
fem