私はしばしば一度に複数の端末(または端末エミュレーター)を使用します。 Xでは、コマンドをコピーして貼り付けることができますが、あまり実用的ではないことに加えて、実際のTTYでは明らかに機能しません。私が思いついた最初のアイデアは似たようなものです。
command > /dev/sometty
残念ながら、command
は実行されますbeforeパイプされ、echo `command`
のようなトリックは、奇妙なbash文字がいくつあっても機能しません($
、`
、"
など)があります。したがって、/dev/sometty
は単にテキストを取得します。
問題は、これらのコマンドをファイルにパイプしたり、実行可能にしたりするだけの価値がある場合もあります。つまり、スクリプトを作成して適切な端末から実行することです。しかし、それは大変な作業です。指示のために、これらのファイルを作成するためのスクリプトを作成することを考えていました。
termpipe -e "command1\ncommand2\"command 1 argument\\n(s)\"" -t /dev/sometty
それは次のようなことをします:
/tmp/termpipe-20140208-153029-1.sh
にパイプしますAFAIK、問題は。にあります:適切な端末で最初のインスタンスを実行するには別のtermpipe
インスタンスが必要なので、これは問題を解決しません。そしてそのための1つ。そしてそのためのもう一つ、ad infinitum。 これは機能しません。またはそれはできますか?...
解決策は、ターミナルごとに名前付きパイプを使用することであり、各開始時に、スクリプトはパイプに受信したものをターミナルに転送し、それを実行するように指示します(一種のデーモン)。
これはうまくいくかもしれないと思いますが、最初のスクリプトを設定する方法がわかりません。どうやって? FIFOそれぞれの端末を実行するためのパイプコマンドを与えるように指示するにはどうすればよいですか? Bashについてあまり知らないので、完全な説明をいただければ幸いです。
this に続いて、あなたの最後の計画をうまく機能させることができます。送信されるコマンドがシェルによって処理されないようにするには、パイプに到達したときに文字列の形式である必要があります(したがって、echo "command"
ではなくecho `command`
)。次に、適切な端末で開始されたバックグラウンドプロセス( alike adaemon、ただし必ずしもそうではありません)によって読み取られる必要があります。 eval 同じプロセスで使用する必要があります。
ただし、パイプごとにスクリプトを作成するのはboiler-plateyです。それでは、スクリプトの作成を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'
のようなエイリアスを無視することに注意してください。これが誰かを助けてくれることを願っています。
上記では、パイプリーダーが必ずしもデーモンではないことについて説明しましたが、実際には、 differences を確認しましたが、この場合、単なるバックグラウンドプロセスになります。このように、ターミナルを閉じると、EXIT
信号(SIGHUP
、SIGTERM
など)もスクリプトによって受信され、パイプが削除されるためです。 (スクリプトのtrap
で始まる行を参照)自動的に、無駄なプロセスとファイル(および無駄なパイプへのリダイレクトがあった場合は他のファイル)を回避します。
それでも、(少なくとも私は)おそらくほとんどの場合必要なスクリプトを実行しなければならないのは退屈です。それでは、自動化しましょう!どの端末でも start である必要があり、それらすべてが読み取るものの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
(および some )の simple REGEXを使用して、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
Vimの変種。 Vimをデフォルトのエディターにする必要があります。
echo "one two three" > new_file.txt
Ctrl + x
Ctrl + e
の組み合わせを押します。 Vim内で長いコマンドが開きます。 Ctrl + g
を押して、vimウィンドウの下部に一時ファイル名を表示します。私の場合は/tmp/bash-fc.230BC2
ですvim /tmp/bash-fc.230BC2
と入力します(もちろん、ファイル名のオートコンプリートを使用します)。 「スワップファイルはすでに存在します」と表示されます。読み取り専用の場合は、O
を押します。y$ : ! Ctrl+r " Enter
y$
-末尾の改行を除く行のすべての文字をコピーします。:
-コマンドラインモードに移動します!
-シェルでコマンドを実行するCtrl+r "
-コピーした行をコマンドラインに貼り付けます。Enter
-コマンドを実行します.vimrc
ファイル編集により、このすべてのキーシーケンスを1つのキーストロークにマッピングできることに注意してください。
コマンドが1つのttyから別のttyにコピーされ、実行されました。