GNU/Linux >> Linux の 問題 >  >> Linux

コマンドを任意の端末にパイプする方法は?

一度に複数の端末(または端末エミュレーター)を使用することがよくあります。 Xでは、コマンドをコピーして貼り付けることができますが、あまり実用的ではないことに加えて、実際のTTYでは明らかに機能しません。私が思いついた最初のアイデアは似たようなものです:

command > /dev/sometty

残念ながら、コマンド に実行されます パイプされており、 echo `command`のようなトリックはありません 奇妙なbash文字( $ )がいくつあっても機能します 、 `" 、など)があります。つまり、 / dev / sometty 単にテキストを取得します。

問題は、場合によっては、これらのコマンドをファイルにパイプしたり、実行可能にしたりする価値があることです。つまり、スクリプトを作成して適切な端末から実行することもできます。しかし、それは大変な作業です。指示のために、これらのファイルを作成するためのスクリプトを作成することを考えていました:

termpipe -e "command1\ncommand2\"command 1 argument\\n(s)\"" -t /dev/sometty 

次のようになります:

  1. コマンドを/tmp/termpipe-20140208-153029-1.shなどにパイプします
  2. ファイルを実行可能にする
  3. 適切な端末でファイルを実行します
  4. 実行が完了したらスクリプトを削除します

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' など) 。これが誰かに役立つことを願っています。

関連:Linux – Arch linux Wi-Fiは手動で動作しますが、自動化するにはどうすればよいですか?

編集(注–非デーモンの利点 ):

上記で、パイプリーダーがデーモンではないことについて話しました 必然的ですが、実際、私は違いを確認しました。この場合、単なるバックグラウンドプロセスである方がはるかに優れていることがわかりました。このように、ターミナルを閉じると、 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

Linux
  1. Bash履歴コマンドの使用方法

  2. ターミナルでHZを確認するには?

  3. Linux でパイプをレート制限する方法は?

  1. Stdoutを複数のコマンドに送信する方法は?

  2. 「タブ完了」によって表示されるコマンドのリストをパイプする方法は?

  3. ターミナルの任意のパスから .sh-script を実行するには?

  1. Linuxコマンドをバックグラウンドで実行する方法

  2. Bash でコマンドのグループをタイムアウトする方法

  3. debian preseed ファイルでコマンドを一緒にパイプするにはどうすればよいですか?