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?
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
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.
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\""
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:~$
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.