Làm thế nào để bắt đầu một thiết bị đầu cuối với văn bản nhất định đã được nhập trên dòng lệnh?


25

Thay vì đọc lại câu hỏi của tôi, hãy để tôi mô tả cho bạn trường hợp người dùng mong muốn:

Tôi tạo một tập lệnh shell ngắn để chạy lệnh "gnome-terminal --someoptionflagname 'văn bản của tôi sẽ được đăng'" và thực thi tập lệnh này.

Gnome-terminal bật lên, với dấu nhắc dòng lệnh theo sau là văn bản của tôi.

I E: fields@mycomputer:/$ my text to be posted

Điều này có thể được thực hiện?


Nếu lỗi này đã được sửa trong Ubuntu, bạn nên xem xét cnee .
ændrük

@ ndrük Nó đã được sửa và tên gói xneebây giờ.
tráng miệng

Câu trả lời:


32

Bạn có thể làm điều này với mong đợi ( cài đặt ). Tạo và thực hiện ~/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

và chạy Gnome Terminal với:

gnome-terminal -e ~/bin/myprompt

+1 để sử dụng Mong đợi. Tôi đã sử dụng điều này trong nhiều năm để giúp tự động hóa rất nhiều thứ.
Marco Ceppi

Điều này thật tuyệt Tôi đã hy vọng sẽ có một số câu trả lời đơn giản (ish) dựa trên chức năng gnome-terminal mặc định, nhưng có vẻ như điều này trả lời công việc.
emf

Cái này đã làm tôi khó chịu quá lâu, tôi gần như không thể nhớ trường hợp sử dụng dự định là gì. Vì vậy, để làm rõ: tôi muốn làm một cái gì đó như "gnome-terminal -e ls", nhưng điều bắt buộc là cửa sổ vẫn mở. Vì vậy, về cơ bản các phím tắt để mở một thiết bị đầu cuối và chạy các lệnh shell. Điều này có làm rõ vấn đề so với câu trả lời của aendruk / msw không?
emf

1
Nếu tất cả những gì bạn muốn là thiết bị đầu cuối vẫn mở sau một lệnh, có nhiều giải pháp đơn giản hơn nhiều .
ændrük

Siêu, cảm ơn. Tôi đã tích hợp thành công tập lệnh này vào tập lệnh shell gọi công cụ tích hợp dữ liệu Pentaho. Sau đó, tôi đã thêm lệnh gọi vào kịch bản này vào trình khởi chạy Unity vào ngày 11.10 và nó hoạt động như một cơ duyên.
bioShark

8

Nếu tôi hiểu chính xác, bạn muốn dòng đầu vào đầu tiên của bạn được điền sẵn vào nội dung mà bạn truyền vào dòng lệnh gnome-terminal.

Tôi không biết làm thế nào để làm điều này chính xác với bash, nhưng đây là thứ gì đó đến gần. Trong của bạn ~/.bashrc, thêm dòng sau vào cuối:

history -s "$BASH_INITIAL_COMMAND"

Chạy gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bashvà nhấn Uptại dấu nhắc để gọi lại văn bản.

Cũng lưu ý rằng nếu bạn đặt set -o historytheo sau bởi các nhận xét ở cuối của bạn .bashrc, chúng sẽ được đưa vào lịch sử khi bash bắt đầu, vì vậy bạn có thể sử dụng chúng làm cơ sở để chỉnh sửa bằng cách lấy chúng bằng Upphím và xóa chữ cái đầu tiên #.


2
Mặc dù không hoàn toàn là giải pháp tôi đang tìm kiếm, nhưng điều này thật thú vị theo đúng nghĩa của nó.
emf

8

Đề xuất của ændrük rất tốt và hiệu quả với tôi, tuy nhiên lệnh được mã hóa cứng trong tập lệnh và nếu bạn thay đổi kích thước cửa sổ đầu cuối thì nó không hoạt động tốt. Sử dụng mã của anh ấy làm cơ sở, tôi đã thêm khả năng gửi tập lệnh myprompt của lệnh làm đối số và tập lệnh này xử lý chính xác thay đổi kích thước cửa sổ đầu cuối.

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

và chạy Gnome Terminal với:

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

1

Câu trả lời của ændrük là tốt, nhưng có lẽ hơi nặng nề cho nhiệm vụ.

Đây là một kịch bản viết một kịch bản dựa trên các đối số của nó

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

Nếu bạn chưa thực hiện nhiều chương trình shell, dường như có nhiều phép thuật ở đây hơn là có. Đầu tiên, tôi đặt tên cho một tệp tạm thời để giữ tập lệnh trong đó $$ID tiến trình của trình bao chạy tập lệnh này. Các /tmp/something.$$ẩn dụ được sử dụng trong trường hợp hai trường hợp kịch bản này đang chạy cùng một lúc, họ sẽ không cố gắng sử dụng các tập tin tạm thời như vậy.

Biến $SHELLđược đặt thành tên của shell đang chạy tập lệnh. Nếu bạn sử dụng / usr / bin / bash, có lẽ bạn cũng muốn tập lệnh mini để sử dụng nó.

Đây "$@"là một thành ngữ shell cho "nội suy tất cả các đối số của tôi, trích dẫn chúng nếu cần". Cú pháp đặc biệt này gây ra

script.sh 'my file' your\ file

để nội suy các đối số là hai phần tử

"my file" "your file"

thay vì bốn $@sẽ mang lại

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

Các dòng cuối cùng của tập lệnh sắp xếp cho một thiết bị đầu cuối gnome để bắt đầu chạy tập lệnh nhỏ và sau đó bắt đầu một vỏ tương tác. Khi gnome-terminal thoát, tập lệnh tạm thời bị xóa vì xả rác là không hợp lệ.

Dòng cuối cùng không phải là một phần của tập lệnh mini, nó chứng tỏ rằng tập lệnh nhỏ hoạt động. Nếu tập lệnh 11 dòng ở trên nằm trong một tệp được gọi rt.shthì tập lệnh chmodsẽ thực thi và sau đó nó được thực thi.

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

Kết quả của tất cả những điều này sẽ là một thiết bị đầu cuối gnome khởi động, hiển thị

hello world

trên dòng đầu tiên và sau đó bắt đầu một vỏ tương tác:

msw@myhost:~$

Tôi nghĩ rằng kịch bản của bạn có thể được giảm xuống gnome-terminal -x sh -c "echo hello world; bash", mà tôi không nghĩ rằng câu hỏi đang được yêu cầu.
ændrük

Điều này có vẻ mát mẻ. Bạn có thể giải thích những gì đang xảy ra ở đây?
emf

1
emfields: Tôi chú thích nó cho bạn.
msw

1
bạn đá cảm ơn các chú thích, loại trợ giúp này giúp cho việc nhập liệu với kịch bản dễ tiếp cận hơn nhiều
emf

0

Hai câu trả lời tôi thích nhất để giải quyết vấn đề này là sử dụng expectvà câu trả lời này mà họ khuyên bạn nên sử dụng --init-filecờ trong shebang hoặc khi thực hiện thiết bị đầu cuối:

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

... và thực hiện nó như:

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 có lẽ là giải pháp tốt hơn (vì lý do tôi sẽ phác thảo), ngoại trừ việc tôi không thể kiểm soát liệu nó có được cài đặt trong môi trường mục tiêu của tôi hay không.

Vấn đề tôi chạy vào với bash của --init-filegnome-terminal--commandnhư một hack để giải quyết này là vỏ không có quyền truy cập vào STDIN trong khi thực hiện các kịch bản init. Ví dụ, nếu tôi muốn chạy một cái gì đó yêu cầu đầu vào của người dùng (ftp, telnet, v.v.) nhưng để vỏ cha mẹ chạy sau đó thì nó sẽ không hoạt động; ngoại lệ duy nhất tôi thấy cho đến nay là ssh:

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

... nhưng những gì tôi cần phức tạp hơn ví dụ về đồ chơi này. Dù sao, tôi hy vọng những --init-filethứ này hữu ích cho bất cứ ai đọc câu hỏi này.


-1

Bạn có thể sử dụng -ehoặc -xđối số để chạy lệnh bên trong thiết bị đầu cuối mới xuất hiện, nhưng đó không chính xác là những gì bạn muốn.


gần, nhưng không hoàn toàn những gì tôi đang tìm kiếm. Một vấn đề, trong trường hợp này, là khi được thực thi và kết thúc, thiết bị đầu cuối sẽ ngay lập tức đóng lại. Vì vậy, giả sử tôi muốn một phím tắt đến "ls ~ / ghi chú", nó sẽ đóng trước khi tôi có thể xem đầu ra.
emf

Nếu có một giải pháp cho vấn đề này, nó sẽ giải quyết hầu hết các trường hợp tôi đang tìm kiếm.
emf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.