Jak uruchomić terminal z pewnym tekstem wprowadzonym już w wierszu poleceń?

25

Zamiast redagować moje pytanie, pozwól, że opiszę Ci pożądany przypadek użytkownika:

Tworzę krótki skrypt powłoki, aby uruchomić polecenie „gnome-terminal - someoptionflagname„ mój tekst do wysłania ”” i wykonać ten skrypt.

Gnome-terminal wyskakuje, z wierszem poleceń i moim tekstem.

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

Czy można to zrobić?

emf
źródło
Jeśli ten błąd zostanie kiedykolwiek naprawiony w Ubuntu, powinieneś zajrzeć do kolana .
ændrük
@ ændrük Zostało to naprawione, a nazwa pakietu jest xneeteraz.
deser

Odpowiedzi:

32

Możesz to zrobić za pomocą funkcji expect ( install ). Utwórz i wykonaj plik wykonywalny ~/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

i uruchom Gnome Terminal z:

gnome-terminal -e ~/bin/myprompt
ændrük
źródło
+1 za używanie Oczekiwania. Używam tego od lat, aby zautomatyzować wiele rzeczy.
Marco Ceppi
To jest fajne. Miałem nadzieję, że będzie jakaś prosta (ish) odpowiedź oparta na domyślnej funkcjonalności terminalu gnome, ale wygląda na to, że odpowiada to zadaniu.
emf
Ten tak długo mnie denerwuje, że prawie nie pamiętam, jaki był zamierzony przypadek użycia. Dla wyjaśnienia: chciałbym zrobić coś w stylu „gnome-terminal -e ls”, ale haczykiem jest pozostawienie otwartego okna. Zatem w zasadzie skróty do otwierania terminala i uruchamiania poleceń powłoki. Czy to wyjaśnia problemy w porównaniu z odpowiedziami aendruk / msw?
emf
1
Jeśli wszystko, czego chcesz, to aby terminal pozostawał otwarty po wydaniu polecenia, istnieją znacznie prostsze rozwiązania .
ændrük
Super dzięki. Z powodzeniem zintegrowałem to ze skryptem powłoki, który wywołuje narzędzie do integracji danych Pentaho. Następnie dodałem wywołanie do tego skryptu do programu uruchamiającego Unity w 11.10 i działa jak urok.
bioShark
8

Jeśli dobrze rozumiem, chcesz, aby pierwszy wiersz wejściowy był wypełniony zawartością przekazywaną w wierszu poleceń gnome-terminal.

Nie wiem, jak to zrobić dokładnie za pomocą bash, ale oto coś, co się zbliża. W swoim ~/.bashrcdodaj następujący wiersz na samym końcu:

history -s "$BASH_INITIAL_COMMAND"

Biegać gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bash i naciśnijUp w monicie, aby przywołać tekst.

Zauważ też, że jeśli umieścisz set -o historyna końcu swoje komentarze .bashrc, zostaną one wprowadzone do historii wraz z rozpoczęciem bash, więc możesz użyć ich jako podstawy do edycji, docierając do nich Upklawiszem i usuwając inicjał #.

Gilles „SO- przestań być zły”
źródło
2
Chociaż nie do końca rozwiązanie, którego szukałem, samo w sobie jest interesujące.
emf
8

Sugestia ændrük jest bardzo dobra i działała dla mnie, jednak polecenie jest zakodowane na stałe w skrypcie, a jeśli zmienisz rozmiar okna terminala, to nie działa dobrze. Używając jego kodu jako podstawy, dodałem możliwość wysłania skryptu myprompt polecenia jako argumentu, a ten skrypt poprawnie obsługuje zmianę rozmiaru okna terminala.

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

i uruchom Gnome Terminal z:

gnome-terminal -e "~/bin/myprompt \"my text to be posted\""
Gordon McCreight
źródło
1

Odpowiedź ændrüka jest dobra, ale może trochę ciężka do zadania.

Oto skrypt, który pisze skrypt na podstawie swoich argumentów

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

Jeśli nie wykonałeś dużo programowania powłoki, wydaje się, że jest tu więcej magii niż jest. Najpierw nazywam plik tymczasowy do przechowywania skryptu, gdzie $$jest identyfikator procesu powłoki uruchamiającej ten skrypt. The/tmp/something.$$Metafora jest stosowana w przypadku dwóch wystąpień tego skryptu są uruchamiane w tym samym czasie, nie będzie próbował użyć tego samego pliku tymczasowego.

Zmienna $SHELL jest ustawiona na nazwę powłoki uruchamiającej skrypt. Jeśli używasz / usr / bin / bash, prawdopodobnie chcesz, aby mini-skrypt również z niego korzystał.

Jest "$@"to idiom powłoki „interpoluj wszystkie moje argumenty, w razie potrzeby przytaczając je”. Ta szczególna składnia powoduje

script.sh 'my file' your\ file

interpolować argumenty jako dwa elementy

"my file" "your file"

zamiast czterech, które $@by się poddały

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

Ostatnie wiersze skryptu określają, że terminal gnome uruchamia mini-skrypt, a następnie uruchamia interaktywną powłokę. Kiedy gnome-terminal kończy pracę, skrypt tymczasowy jest usuwany, ponieważ śmiecenie jest niestosowne.

Ostatni wiersz nie jest częścią mini-skryptu, pokazuje, że mini-skrypt działa. Jeśli powyższy 11-wierszowy skrypt znajduje się w pliku o nazwie, rt.shto chmodpowoduje, że jest wykonywalny, a następnie jest wykonywany.

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

Wynikiem tego wszystkiego będzie terminal gnome, który się uruchomi

hello world

w pierwszym wierszu, a następnie uruchamia interaktywną powłokę:

msw@myhost:~$
msw
źródło
Myślę, że twój skrypt może zostać zredukowany do gnome-terminal -x sh -c "echo hello world; bash", czego nie sądzę.
ændrük
To wygląda świetnie. Czy możesz wyjaśnić, co się tutaj dzieje?
emf
1
emfields: Zanotowałem to dla ciebie.
msw 10.10
1
rządzisz. dzięki za adnotacje, ten rodzaj pomocy sprawia, że ​​bariera wejścia ze skryptów jest znacznie bardziej dostępna
emf
0

Dwie odpowiedzi, które najbardziej podobały mi się w rozwiązaniu, są następujące expecti ta, w której zalecają użycie --init-fileflagi w shebang lub podczas uruchamiania terminala:

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

... i wykonaj go jako:

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 jest prawdopodobnie lepszym rozwiązaniem (z powodów, które przedstawię), z wyjątkiem tego, że nie mogę kontrolować, czy jest zainstalowany w moim środowisku docelowym.

Problem z bash wpadł na --init-filea gnome-terminal„s --commandjako hack do rozwiązania Jest to powłoka nie ma dostępu do standardowego wejścia podczas wykonywania skrypty inicjujące. Jeśli na przykład chcę uruchomić coś, co wymagałoby wprowadzenia danych przez użytkownika (ftp, telnet itp.), Ale pozostawienie uruchomionej powłoki nadrzędnej nie zadziała; jedynym wyjątkiem, jaki do tej pory widziałem, jest ssh:

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

... ale to, czego potrzebuję, jest bardziej skomplikowane niż ten przykład zabawki. W każdym razie mam nadzieję, że --init-filete informacje będą przydatne dla każdego, kto czyta to pytanie.

Brian Vandenberg
źródło
-1

Możesz użyć argumentów -elub, -xaby uruchomić polecenie w nowo wyskakującym terminalu, ale nie jest to dokładnie to, czego chcesz.

Karl Bielefeldt
źródło
blisko, ale nie do końca to, czego szukam. Jednym z problemów w tym przypadku jest to, że po uruchomieniu i zakończeniu terminal natychmiast się zamknie. Powiedzmy, że chcę skrót do „ls ~ / notes”, zostanie on zamknięty, zanim będę mógł wyświetlić wynik.
emf
Gdyby było na to rozwiązanie, rozwiązałoby to większość spraw, których szukam.
emf