一度に複数の端末(または端末エミュレーター)を使用することがよくあります。 Xでは、コマンドをコピーして貼り付けることができますが、あまり実用的ではないことに加えて、実際のTTYでは明らかに機能しません。私が思いついた最初のアイデアは似たようなものです:
command > /dev/sometty
残念ながら、コマンド
前に実行されます パイプされており、 echo `command`
のようなトリックはありません 奇妙なbash文字( $
)がいくつあっても機能します 、 `
、"コード> 、など)があります。つまり、
/ dev / sometty
単にテキストを取得します。
問題は、場合によっては、これらのコマンドをファイルにパイプしたり、実行可能にしたりする価値があることです。つまり、スクリプトを作成して適切な端末から実行することもできます。しかし、それは大変な作業です。指示のために、これらのファイルを作成するためのスクリプトを作成することを考えていました:
termpipe -e "command1\ncommand2\"command 1 argument\\n(s)\"" -t /dev/sometty
次のようになります:
- コマンドを
/tmp/termpipe-20140208-153029-1.sh
などにパイプします - ファイルを実行可能にする
- 適切な端末でファイルを実行します
- 実行が完了したらスクリプトを削除します
AFAIK、問題は3にあります。 :別の termpipe
が必要になるため、これで問題が解決することはありません。 適切な端末で最初に実行するインスタンス。そしてそのための1つ。そしてもう1つ、 ad infinitum 。 したがって、これは機能しません。 それともできますか?…
解決策は、端末ごとに名前付きパイプを使用することです。各起動時に、スクリプトはパイプに、受信したものをすべて端末に転送し、それを実行するように指示します(一種のデーモンのように) 。
これはうまくいくと思いますが、最初のスクリプトを設定する方法がわかりません。どうやって? FIFOに、それぞれの端末を実行するためのパイプコマンドを与えるように指示するにはどうすればよいですか? Bashについてはあまり知らないので、完全な説明をいただければ幸いです。
承認された回答:
これに続いて、あなたの最後の計画をうまく機能させることができます。送信されるコマンドがシェルによって処理されないようにするには、パイプに到達したときに文字列の形式である必要があります(したがって、 echo "command"
、 echo `command`
ではありません )。次に、バックグラウンドプロセス(デーモンなど)で読み取る必要があります。 、ただし必ずしもそうとは限りません)適切な端末で開始しました。同じプロセスで評価する必要があります。
しかし、それはボイラープレート パイプごとにスクリプトを作成します。それでは、スクリプトの作成を term-pipe-r.sh
として一般化しましょう。 ( chmod + x
を忘れないでください それ!):
#!/bin/bash
pipe=$1 # the pipe name is the first argument
trap 'rm -f "$pipe"' EXIT # ignore exit and delete messages until the end
if [[ ! -p $pipe ]]; then # if the pipe doesn't exist, create it
mkfifo $pipe
fi
while true # cycle eternally..
do
if read line <$ pipe; then
if [[ "$line" == 'close the term-pipe pipe' ]]; then
break
# if the pipe closing message is received, break the while cycle
fi
echo # a line break should be used because of the prompt
eval $line # run the line: as this script should be started
fi # in the target terminal,
done # the line will be run there.
echo "<pipe closing message>" # custom message on the end of the script
つまり、 / dev / tty3
が必要だとしましょう コマンドを受け取るには:そこに行ってください
./term-pipe-r.sh tty3pipe & # $1 will be tty3pipe (in a new process)
また、任意の端末からコマンドを送信します (それ自体からでも):
echo "command" > tty3pipe
またはそこでファイルを実行するには:
cat some-script.sh > tty3pipe
このパイピングは.bashrc
のようなファイルを無視することに注意してください 、およびその中のエイリアス( alias ls ='ls --color'
など) 。これが誰かに役立つことを願っています。
編集(注–非デーモンの利点 ):
上記で、パイプリーダーがデーモンではないことについて話しました 必然的ですが、実際、私は違いを確認しました。この場合、単なるバックグラウンドプロセスである方がはるかに優れていることがわかりました。このように、ターミナルを閉じると、 EXIT
シグナル( SIGHUP
、 SIGTERM
、またはその他)もスクリプトによって受信され、パイプが削除されます( trap
で始まる行を参照してください)。 スクリプト内で)自動的に、役に立たないプロセスとファイル(および、役に立たないパイプへのリダイレクトがあった場合は他のプロセスとファイル)を回避します。
編集(自動化):
それでも、おそらくほとんどの場合、あなた(少なくとも私)が望むスクリプトを実行しなければならないのは退屈です。それでは、自動化しましょう。それはどの端末でも開始する必要があり、それらすべてが読み取るものの1つは .bashrc
です。 。さらに、 ./ term-pipe-r.sh
を使用する必要があるのは残念です。 。したがって、次のことを行うことができます:
cd /bin # go to /bin, where Bash gets command names
ln -s /directory/of/term-pipe-r.sh tpr # call it tpr (terminal pipe reader)
これを実行するには、 tpr tty3pipe&
だけが必要です。 / dev / tty3
にあります いつでも好きなときに。しかし、それを自動的に実行できるのに、なぜそれを行うのでしょうか。したがって、これを .bashrc
に追加する必要があります 。しかし待ってください:パイプ名をどうやって知るのでしょうか? TTY( tty
で知ることができます)に基づいて名前を付けることができます コマンド)、 sed
で単純な正規表現を使用 (そしていくつかのトリック)。 〜/ .bashrc
に追加する必要があるもの その後、次のようになります:
pipe="$(sed 's/\/dev\///' <<< `tty` | sed 's/\///')pipe"
# ^^^- take out '/dev/' and other '/', add 'pipe'
tpr $pipe & # start our script with the appropriate pipe name