web-dev-qa-db-fra.com

Comment démarrer un terminal avec un certain texte déjà saisi sur la ligne de commande?

Plutôt que de reformuler ma question, laissez-moi vous décrire le cas d'utilisation souhaité:

Je crée un court script Shell pour exécuter la commande "gnome-terminal --someoptionflagname" mon texte à publier "" et exécuter ce script.

Gnome-terminal apparaît, avec une invite de ligne de commande suivie de mon texte.

c'est-à-dire: fields@mycomputer:/$ my text to be posted

Cela peut-il être fait?

25
emf

Vous pouvez le faire avec attendez ( installez ). Créer et rendre exécutable ~/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

et lancez Gnome Terminal avec:

gnome-terminal -e ~/bin/myprompt
32
ændrük

Si je comprends bien, vous souhaitez que votre première ligne de saisie soit préremplie pour le contenu que vous transmettez sur la ligne de commande gnome-terminal.

Je ne sais pas comment faire exactement cela avec bash, mais voici quelque chose qui se rapproche. Dans votre ~/.bashrc, ajoutez la ligne suivante à la fin:

history -s "$BASH_INITIAL_COMMAND"

Exécutez gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bash et appuyez sur Up à l'invite pour rappeler le texte.

Notez également que si vous mettez set -o history suivi de commentaires à la fin de votre .bashrc, ils seront entrés dans l’historique au début de bash. Vous pourrez donc les utiliser comme base d’édition en les atteignant avec le Up clé et en supprimant le # initial.

8
Gilles

la suggestion de ændrük est très bonne et a fonctionné pour moi. Cependant, la commande est codée en dur dans le script et si vous redimensionnez la fenêtre du terminal, elle ne fonctionnera pas bien. En utilisant son code comme base, j'ai ajouté la possibilité d'envoyer la commande sous forme d'argument au script myprompt, et ce script gère correctement le redimensionnement de la fenêtre du 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

et lancez Gnome Terminal avec:

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

la réponse d'ændrük est bonne, mais peut-être un peu lourd pour la tâche.

Voici un script qui écrit un script basé sur ses arguments

#!/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 vous n’avez pas fait beaucoup de programmation Shell, il semble y avoir plus de magie qu’il n’y en a. Premièrement, je nomme un fichier temporaire contenant le script, où $$ est l’ID de processus du shell qui exécute ce script. La métaphore /tmp/something.$$ est utilisée dans le cas où deux instances de ce script sont exécutées en même temps, elles n'essaieront pas d'utiliser le même fichier temporaire.

La variable $Shell est définie sur le nom du shell exécutant le script. Si vous utilisez/usr/bin/bash, vous voudrez probablement que le mini-script l’utilise également.

Le "$@" est un idiome du shell pour "interpoler tous mes arguments, en les citant si nécessaire". Cette syntaxe particulière provoque

script.sh 'my file' your\ file

interpoler les arguments en deux éléments

"my file" "your file"

au lieu des quatre que $@ donnerait

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

Les dernières lignes du script permettent à un terminal gnome de lancer l’exécution du mini-script, puis de lancer un shell interactif. Lorsque le gnome-terminal se ferme, le script temporaire est supprimé car la litière n'est pas cool.

La dernière ligne ne fait pas partie du mini-script, elle montre que le mini-script fonctionne. Si le script de 11 lignes ci-dessus se trouve dans un fichier appelé rt.sh, le chmod le rend exécutable, puis il est exécuté.

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

Le résultat de tout cela sera un terminal gnome qui démarre, affiche

hello world

sur sa première ligne puis démarre un shell interactif:

msw@myhost:~$
1
msw

Les deux réponses que j'ai le mieux aimé résoudre ce problème utilisent expect et celui-ci où ils recommandent d'utiliser l'indicateur --init-file soit dans Shebang, soit lors de l'exécution du terminal:

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

... et l'exécuter comme:

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 est probablement la meilleure solution (pour des raisons que je vais exposer), sauf que je ne peux pas contrôler si elle est installée dans mon environnement cible.

Le problème que j'ai rencontré avec --init-file de ___ et gnome-terminal de _--command de bash en tant que solution pour résoudre ce problème est que le shell n'a pas accès à STDIN lors de l'exécution des scripts d'initialisation. Si, par exemple, je veux exécuter quelque chose qui nécessiterait une entrée de l'utilisateur (ftp, telnet, etc.) mais laisser le shell Shell en cours d'exécution après cela ne fonctionnera pas; La seule exception que j'ai vue jusqu'à présent est ssh:

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

... mais ce dont j'ai besoin est plus compliqué que cet exemple de jouet. Quoi qu'il en soit, j'espère que le contenu de --init-file sera utile à quiconque lira cette question.

0
Brian Vandenberg