Wie starte ich ein Terminal mit einem bestimmten Text, der bereits in der Befehlszeile eingegeben wurde?

25

Anstatt meine Frage neu zu formulieren, möchte ich Ihnen den gewünschten Anwenderfall beschreiben:

Ich erstelle ein kurzes Shell-Skript, um den Befehl "gnome-terminal --someoptionflagname 'my text to be posted'" auszuführen, und führe dieses Skript aus.

Das Gnome-Terminal erscheint mit der Kommandozeile gefolgt von meinem Text.

dh: fields@mycomputer:/$ my text to be posted

Kann das gemacht werden?

emf
quelle
Wenn dieser Fehler jemals in Ubuntu behoben wurde, sollten Sie sich mit Cnee befassen .
ændrük
@ ændrük Es ist behoben und der Paketname ist xneejetzt.
Dessert

Antworten:

32

Sie können dies mit expect ( install ) tun . Erstellen und ausführbar machen ~/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

und starte Gnome Terminal mit:

gnome-terminal -e ~/bin/myprompt
ændrük
quelle
+1 für die Verwendung von Expect. Ich habe dies jahrelang verwendet, um viele Dinge zu automatisieren.
Marco Ceppi
Das ist cool. Ich hatte gehofft, dass es eine einfache (ish) Antwort geben würde, die auf der Standard-Gnome-Terminal-Funktionalität basiert, aber so sieht es aus, als würde dies den Job beantworten.
EMF
Dieser nervt mich schon so lange, dass ich mich fast nicht mehr an den beabsichtigten Anwendungsfall erinnern kann. Zur Verdeutlichung: Ich würde gerne so etwas wie "gnome-terminal -e ls" machen, aber der Haken ist, dass das Fenster offen bleibt. Im Grunde genommen also Verknüpfungen zum Öffnen eines Terminals und zum Ausführen von Shell-Befehlen. Klärt dies Probleme im Vergleich zu den Antworten von aendruk / msw?
EMF
1
Wenn das Terminal nach einem Befehl nur geöffnet bleiben soll, gibt es viel einfachere Lösungen .
ændrük,
Super, danke. Ich habe dies erfolgreich in ein Shell-Skript integriert, das das Pentaho-Datenintegrationstool aufruft. Dann habe ich den Aufruf dieses Skripts zu Unity Launcher in 11.10 hinzugefügt, und es funktioniert wie ein Zauber.
BioShark
8

Wenn ich das richtig verstehe, soll Ihre erste Eingabezeile vorab mit Inhalten gefüllt werden, die Sie über die Gnome-Terminal-Befehlszeile übergeben.

Ich weiß nicht, wie ich genau das mit bash machen soll, aber hier ist etwas, das nahe kommt. Fügen Sie in Ihrer ~/.bashrcZeile ganz am Ende die folgende Zeile hinzu:

history -s "$BASH_INITIAL_COMMAND"

Führen Sie aus gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bash, und drücken Sie Upan der Eingabeaufforderung, um den Text abzurufen.

Beachten Sie auch, dass, wenn Sie set -o historyam Ende des .bashrcVerlaufs einen Kommentar gefolgt von einem Kommentar einfügen, dieser beim Start der Bash in den Verlauf aufgenommen wird. Sie können ihn als Grundlage für die Bearbeitung verwenden, indem Sie ihn mit der UpTaste erreichen und den Anfangsbuchstaben entfernen #.

Gilles 'SO - hör auf böse zu sein'
quelle
2
Obwohl dies nicht ganz die Lösung ist, nach der ich gesucht habe, ist dies an sich schon interessant.
EMF
8

ændrüks Vorschlag ist sehr gut und hat für mich funktioniert, der Befehl ist jedoch im Skript fest codiert, und wenn Sie die Größe des Terminalfensters ändern, funktioniert er nicht gut. Unter Verwendung seines Codes als Basis habe ich die Möglichkeit hinzugefügt, dem myprompt-Skript den Befehl als Argument zu senden, und dieses Skript behandelt die Größenänderung des Terminalfensters korrekt.

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

und starte Gnome Terminal mit:

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

ændrüks Antwort ist in Ordnung, aber vielleicht ein bisschen schwergewichtig für die Aufgabe.

Hier ist ein Skript, das ein Skript basierend auf seinen Argumenten schreibt

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

Wenn Sie nicht viel Shell-Programmierung gemacht haben, scheint es hier mehr Magie zu geben als dort. Zuerst benenne ich eine temporäre Datei für das Skript, in der $$die Prozess-ID der Shell steht, in der dieses Skript ausgeführt wird. Die /tmp/something.$$Metapher wird verwendet, wenn zwei Instanzen dieses Skripts gleichzeitig ausgeführt werden. Sie werden nicht versuchen, dieselbe temporäre Datei zu verwenden.

Die Variable $SHELLwird auf den Namen der Shell gesetzt, auf der das Skript ausgeführt wird. Wenn Sie / usr / bin / bash verwenden, möchten Sie wahrscheinlich, dass das Miniskript es auch verwendet.

Das "$@"ist ein Shell-Idiom für "interpoliere alle meine Argumente und zitiere sie, wenn nötig". Diese eigenartige Syntax bewirkt

script.sh 'my file' your\ file

die Argumente als zwei Elemente zu interpolieren

"my file" "your file"

anstelle der vier, $@die nachgeben würden

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

Die letzten Zeilen des Skripts sorgen dafür, dass ein Gnome-Terminal das Mini-Skript ausführt und anschließend eine interaktive Shell startet. Wenn das Gnome-Terminal beendet wird, wird das temporäre Skript entfernt, da die Müllablagerung nicht mehr korrekt ist.

Die letzte Zeile ist kein Teil des Miniskripts. Sie zeigt, dass das Miniskript funktioniert. Wenn sich das 11-Zeilen-Skript in einer Datei befindet, die aufgerufen rt.shwird, chmodmacht die es ausführbar und dann wird es ausgeführt.

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

Das Ergebnis all dessen ist ein Gnom-Terminal, das gestartet wird und angezeigt wird

hello world

in der ersten Zeile und startet dann eine interaktive Shell:

msw@myhost:~$
msw
quelle
Ich denke, Ihr Skript könnte auf das reduziert werden gnome-terminal -x sh -c "echo hello world; bash", was ich nicht für die Frage halte.
ændrük
Das sieht cool aus. Können Sie erklären, was hier passiert?
EMF
1
emfields: Ich habe es für dich kommentiert.
msw
1
du rockst danke für die anmerkungen, diese art von
hilfe erleichtert den einstieg in das scripting
0

Die beiden Antworten , die ich gemocht habe dies am besten zu lösen verwenden expectund diese , wo sie mit dem empfehlen --init-fileFlag entweder im shebang oder bei der Ausführung des Terminals:

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

... und führe es aus als:

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 ist wahrscheinlich die bessere Lösung (aus Gründen, die ich skizzieren werde), außer dass ich nicht kontrollieren kann, ob es in meiner Zielumgebung installiert ist.

Das Problem , das ich lief in mit bash --init-fileund gnome-terminalist --commandals ein Hack zu lösen diese die Schale haben keinen Zugriff auf STDIN während Init - Skripte ausgeführt werden . Wenn ich zum Beispiel etwas ausführen möchte, für das Benutzereingaben erforderlich wären (FTP, Telnet usw.), die übergeordnete Shell danach jedoch ausgeführt wird, funktioniert dies nicht. Die einzige Ausnahme, die ich bisher gesehen habe, ist ssh:

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

... aber was ich brauche, ist komplizierter als dieses Spielzeugbeispiel. Wie auch immer, ich hoffe, das --init-fileZeug ist für jeden nützlich, der diese Frage liest.

Brian Vandenberg
quelle
-1

Sie können die Argumente -eoder verwenden -x, um einen Befehl in einem neu aufgerufenen Terminal auszuführen, aber das ist nicht genau das, was Sie wollen.

Karl Bielefeldt
quelle
nah dran, aber nicht ganz das, wonach ich suche. In diesem Fall besteht ein Problem darin, dass das Terminal sofort geschlossen wird, wenn es ausgeführt und beendet wird. Angenommen, ich möchte eine Verknüpfung zu "ls ~ / notes", die geschlossen wird, bevor ich die Ausgabe anzeigen kann.
EMF
Wenn es eine Lösung dafür gäbe, würde sie die meisten Fälle lösen, nach denen ich suche.
EMF