web-dev-qa-db-ja.com

コマンドラインで既に入力されている特定のテキストで端末を起動するにはどうすればいいですか?

質問を言い換えるのではなく、希望するユーザーケースを説明しましょう。

「gnome-terminal --someoptionflagname '投稿するテキスト'」コマンドを実行する短いシェルスクリプトを作成し、このスクリプトを実行します。

Gnome-terminalがポップアップ表示され、コマンドラインプロンプトの後にテキストが表示されます。

すなわち:fields@mycomputer:/$ my text to be posted

これはできますか?

25
emf

これは expectinstall )で行えます。実行可能ファイルを作成して~/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

gnomeターミナルを次のコマンドで実行します:

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

正しく理解できれば、最初の入力行をgnome-terminalコマンド行で渡す内容に事前に入力しておく必要があります。

これをbashで正確に行う方法はわかりませんが、ここに近づいてきました。 ~/.bashrcで、最後に次の行を追加します。

history -s "$BASH_INITIAL_COMMAND"

gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bashを実行し、を押します Up プロンプトでテキストをリコールします。

また、set -o historyの後に.bashrcの最後にコメントを置くと、bashの開始時にコメントが履歴に入力されるので、コメントにアクセスして編集の基礎として使用できます。その Up キーと最初の#を削除します。

8
Gilles

ændrükの提案は非常に良く、私にとってはうまくいきましたが、コマンドはスクリプト内にハードコードされており、ターミナルウィンドウのサイズを変更するとうまく機能しません。彼のコードをベースとして、コマンドとして引数としてmypromptスクリプトを送信する機能を追加しました。このスクリプトはターミナルウィンドウのサイズ変更を正しく処理します。

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

gnomeターミナルを次のコマンドで実行します:

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

ændrükの答えは問題ありませんが、おそらくこのタスクには少し重いでしょう。

引数に基づいてスクリプトを作成するスクリプトを次に示します

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

シェルプログラミングをあまり行っていない場合は、ここよりも多くの魔法があるように見えます。まず、スクリプトを保持する一時ファイルに名前を付けます。$$は、このスクリプトを実行しているシェルのプロセスIDです。 /tmp/something.$$メタファーは、このスクリプトの2つのインスタンスが同時に実行される場合に使用され、同じ一時ファイルを使用しようとしません。

変数$Shellは、スクリプトを実行しているシェルの名前に設定されます。/usr/bin/bashを使用している場合、おそらくミニスクリプトでも使用したいでしょう。

"$@"は「必要に応じて引用してすべての引数を補間する」ためのシェルのイディオムです。この独特の構文は

script.sh 'my file' your\ file

引数を2つの要素として補間する

"my file" "your file"

$@がもたらす4つの代わりに

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

スクリプトの最後の行では、gnome-terminalがミニスクリプトの実行を開始してから、対話型シェルを開始するように調整しています。 gnome-terminalが終了すると、ポイ捨てがクールではないため、一時スクリプトが削除されます。

最後の行はミニスクリプトの一部ではなく、ミニスクリプトが機能することを示しています。上記の11行のスクリプトがrt.shというファイル内にある場合、chmodによって実行可能になり、実行されます。

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

このすべての結果は、起動して表示されるgnome端末になります

hello world

最初の行で、対話型シェルを開始します。

msw@myhost:~$
1
msw

これを解決するために私が最も気に入った2つの答えは、expectthis one を使用することです。シバンまたはターミナルの実行時に--init-fileフラグを使用することをお勧めします。

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

...そして次のように実行します:

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がおそらくより良いソリューションです(理由を説明します)。

これを解決するためのハックとして、bashの--init-filegnome-terminal--commandで遭遇した問題は、シェルがinitスクリプトの実行中にSTDINにアクセスできないことです。たとえば、ユーザー入力(ftp、telnetなど)を必要とするものを実行したいが、その後親のシェルを実行したままにしたい場合は機能しません。これまで見てきた唯一の例外はsshです:

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

...しかし、私が必要なのはこのおもちゃの例よりも複雑です。とにかく、--init-fileがこの質問を読んでいる人にとって役に立つことを願っています。

0