Come avviare un terminale con un determinato testo già inserito nella riga di comando?


25

Invece di riformulare la mia domanda, lascia che ti descriva il caso utente desiderato:

Creo un breve script shell per eseguire il comando "gnome-terminal --someoptionflagname 'il mio testo da inviare'" ed eseguo questo script.

Viene visualizzato Gnome-terminal, con il prompt della riga di comando seguito dal mio testo.

vale a dire: fields@mycomputer:/$ my text to be posted

Può essere fatto?


Se questo bug viene mai risolto in Ubuntu, dovresti esaminare cnee .
ændrük,

@ ændrük È stato risolto e il nome del pacchetto è xneeora.
dessert,

Risposte:


32

Puoi farlo con prevedono ( installa ). Creare e rendere eseguibile ~/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

ed esegui Gnome Terminal con:

gnome-terminal -e ~/bin/myprompt

+1 per l'utilizzo di Expect. L'ho usato per anni per automatizzare molte cose.
Marco Ceppi

Questo è fico. Speravo che ci sarebbe stata una risposta semplice (ish) basata sulla funzionalità gnome-terminal predefinita, ma sembra che questo risponda al lavoro.
emf

Questo mi ha infastidito così a lungo, che quasi non riuscivo a ricordare quale fosse il caso d'uso previsto. Quindi, per chiarimenti: vorrei fare qualcosa come "gnome-terminal -e ls", ma il trucco è che la finestra rimanga aperta. Quindi, in sostanza, scorciatoie per aprire un terminale ed eseguire comandi shell. Questo chiarisce i problemi rispetto alle risposte di aendruk / msw?
emf

1
Se tutto ciò che vuoi è che il terminale rimanga aperto dopo un comando, ci sono soluzioni molto più semplici .
ændrük,

Super grazie. L'ho integrato con successo in uno script di shell che chiama lo strumento di integrazione dati Pentaho. Poi ho aggiunto la chiamata a questo script al programma di avvio di Unity in 11.10 e funziona come un incantesimo.
bioShark,

8

Se ho capito bene, vuoi che la tua prima riga di input sia precompilata ai contenuti che passi sulla riga di comando di gnome-terminal.

Non so come fare esattamente questo con bash, ma ecco qualcosa che si avvicina. Nel tuo ~/.bashrc, aggiungi la seguente riga alla fine:

history -s "$BASH_INITIAL_COMMAND"

Esegui gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bashe premere Upal prompt per richiamare il testo.

Si noti inoltre che se si inseriscono set -o historyseguiti da commenti alla fine .bashrc, verranno inseriti nella cronologia all'avvio di bash, quindi è possibile utilizzarli come base per la modifica raggiungendoli con la Upchiave e rimuovendo l'iniziale #.


2
Sebbene non sia proprio la soluzione che stavo cercando, questo è interessante a sé stante.
emf

8

Il suggerimento di ændrük è molto buono e ha funzionato per me, tuttavia il comando è codificato nello script e se ridimensionate la finestra del terminale non funziona bene. Usando il suo codice come base, ho aggiunto la possibilità di inviare il comando myprompt al comando come argomento, e questo script gestisce correttamente il ridimensionamento della finestra del terminale.

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

ed esegui Gnome Terminal con:

gnome-terminal -e "~/bin/myprompt \"my text to be posted\""

1

La risposta di ændrük va bene, ma forse un po 'pesante per il compito.

Ecco uno script che scrive uno script in base ai suoi argomenti

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

Se non hai fatto molta programmazione della shell, qui sembra esserci più magia di quanta ce ne sia. Innanzitutto, desidero un file temporaneo per contenere lo script in cui si $$trova l'ID del processo della shell che esegue questo script. Il/tmp/something.$$ metafora viene utilizzata nel caso in cui due istanze di questo script vengano eseguite contemporaneamente, non tenteranno di utilizzare lo stesso file temporaneo.

La variabile $SHELL è impostata sul nome della shell che esegue lo script. Se usi / usr / bin / bash, presumibilmente vorresti che anche il mini-script lo usasse.

Il "$@"è un linguaggio di shell per "interpolare tutte le mie argomentazioni, citando loro, se necessario". Questa peculiare sintassi causa

script.sh 'my file' your\ file

per interpolare gli argomenti come due elementi

"my file" "your file"

invece dei quattro che $@avrebbero ceduto

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

Le ultime righe dello script prevedono che un terminale gnome inizi a eseguire il mini-script e quindi a avviare una shell interattiva. Quando lo gnome-terminal esce, lo script temporaneo viene rimosso perché i rifiuti non sono freddi.

L'ultima riga non fa parte del mini-script, dimostra che il mini-script funziona. Se lo script di 11 righe sopra si trova in un file chiamato, rt.shlo chmodrende eseguibile e quindi viene eseguito.

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

Il risultato di tutto ciò sarà un terminale GNOME che si avvia, visualizza

hello world

sulla sua prima riga e quindi avvia una shell interattiva:

msw@myhost:~$

Penso che la tua sceneggiatura potrebbe essere ridotta a gnome-terminal -x sh -c "echo hello world; bash", cosa che non penso sia la domanda.
ændrük,

Sembra fantastico. Puoi spiegare cosa sta succedendo qui?
emf

1
emfields: l'ho annotato per te.
msw,

1
Sei forte. grazie per le annotazioni, questo tipo di aiuto rende molto più accessibile l'accesso agli script con lo script
emf

0

Le due risposte che mi sono piaciute di più per risolvere questo stanno usando expecte questo è quello in cui raccomandano di usare il --init-fileflag nello shebang o quando si esegue il terminale:

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

... ed eseguilo come:

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 è probabilmente la soluzione migliore (per motivi che descriverò), tranne per il fatto che non posso controllare se è installato nel mio ambiente di destinazione.

Il problema con cui mi sono imbattuto con bash's --init-fileed gnome-terminalè --commandstato un hack per risolvere questo problema è che la shell non ha accesso a STDIN durante l'esecuzione degli script di init. Se, ad esempio, voglio eseguire qualcosa che richiederebbe l'input dell'utente (ftp, telnet, ecc.) Ma lasciare in esecuzione la shell genitore in seguito non funzionerà; l'unica eccezione che ho visto finora è ssh:

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

... ma quello di cui ho bisogno è più complicato di questo esempio di giocattolo. Spero comunque che le --init-filecose siano utili a chiunque legga questa domanda.


-1

È possibile utilizzare gli argomenti -eo -xper eseguire un comando all'interno di un terminale appena spuntato, ma non è esattamente quello che si desidera.


vicino, ma non proprio quello che sto cercando. Un problema, in questo caso, è che quando eseguito e terminato, il terminale si chiuderà immediatamente. Quindi, diciamo che voglio un collegamento a "ls ~ / notes", si chiuderà prima di poter visualizzare l'output.
emf

Se ci fosse una soluzione a questo, risolverebbe la maggior parte dei casi che sto cercando.
emf
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.