それで、最近ファイルを介してTCPパケットを送信する方法を見つけましたが/dev/tcp/hostname/port
、最大の問題はそれをどのように受け取るかです。 TCPサーバーをホストできるbashスクリプトとTCPクライアントとして機能する別のスクリプトを作成したいと思います。少しの助けが良いでしょう。私もこれを学習経験にしていることを指摘したいと思います。これが私が望むことをする方法としてssh
またはを使用しない理由です。telnet
答え1
~によるとこれ、いいえ。bash
試していないのでできません。bind(2)
ソケットですが、試してみてください。connect(2)
。
netcat
サーバーを起動するいくつかの方法は次のとおりです。
(私は使うnmap
~のncat
なぜなら牛に似た一種の栄養nc
2004年以降のアップデートを見たことがない)
local $ :|{ ncat -l 9999 --keep-open --allow localhost |
local > PS1='ncat $ ' PS2='ncat > ' dash +m -i 2>&1
local > } 1<>/dev/fd/0
[1] + Running : | { ncat -l 9999 --keep-open --allow localhost | PS1='ncat $ ' PS2='ncat > ' dash +m -i 2>&1; } 1<>/dev/fd/0
最後の:|
パイプを借りました。dash
そこに書いてncat
読んでください。:
もちろん、nullコマンドには必要ないからです。時にはそれよりも簡単ですmkfifo
。
とにかく、ポイントは、作成されたすべてのコンテンツがstdinにパイプさncat
れ、作成されたすべてのコンテンツがstdinにパイプされることです。わかりました、そうではありませんが修正します。ただし、少なくともこのオプションは知っておく必要があります。dash
dash
ncat
bash
+m
local $ ncat localhost 9999
ncat $ echo $0 $$
dash 31231
ncat $ ls -l /dev/fd/[012]
lr-x------ 1 mikeserv mikeserv 64 Dec 11 23:28 /dev/fd/0 -> pipe:[3563412]
l-wx------ 1 mikeserv mikeserv 64 Dec 11 23:28 /dev/fd/1 -> pipe:[3567682]
l-wx------ 1 mikeserv mikeserv 64 Dec 11 23:28 /dev/fd/2 -> pipe:[3567682]
ncat $ ^C
local $
+m
通常、デフォルトで対話型シェルが開くように設定されている監視対象のジョブ制御シェルが制御-m
端末-i
からデータを読み取ろうとし、デフォルトでSIGTTIN
自動的に一時停止するか、そうでない場合(無視またはブロックしようとする場合)殺す。
[1] + Stopped(SIGTTIN) : | { ncat -l 9999 | dash -i 2>&1; } 1<>/dev/fd/0
しかし、ここに端末はありません。出力からわかるようにパイプだけであるls
ため、-m
モニタリングは不可能です。
bash
結局のところ、初期の対話型端末接続は無効になってもあまり柔軟ではないようですreadline
。
[1] + Stopped(SIGTTIN) : | { ncat -l 9999 | bash --noediting +m -i 2>&1 ; } 1<>/dev/fd/0
だから何をしますか?まあ、疑似端末が必要です。シミュレータにあるのと同じです。
local $ ls -l /dev/fd/[012]
lrwx------ 1 mikeserv mikeserv 64 Dec 11 23:30 /dev/fd/0 -> /dev/pts/0
lrwx------ 1 mikeserv mikeserv 64 Dec 11 23:30 /dev/fd/1 -> /dev/pts/0
lrwx------ 1 mikeserv mikeserv 64 Dec 11 23:30 /dev/fd/2 -> /dev/pts/0
/dev/ptmx
Linuxシステムのマスターデバイスから1つを取得できます。tty
(最初にグループのメンバーになりたくない場合は、ユーザーがグループのメンバーである必要があるかもしれませんchown
。)。もし私たちが<
open(2)
ptmx デバイスは、次の場合に新しい疑似端末を生成します。unlockpt(3)
読み書きできる新しいデバイスファイルです。
しばらく前に、私はシェルを使ってこれを行う簡単な方法がないことがわかりました。私はそれのために小さなCプログラムを書いた。。いくつかの説明と簡単な組み立て手順を確認できます。(実際にはシェルプロンプトにコピー/貼り付けるだけです)そのリンクから - これはpts
私が以下で使用するプログラムです。
local $ { 9>&- setsid -c -- bash <> "$({ pts &&
local > >&9 ncat -l 9999 -k --allow localhost
local > } <&9 &)" 2>&0 >&2 ; } 9<> /dev/ptmx
local $
bash
開始がある会議の主催者擬似端末で標準出力のロックを解除し、名前を付けます。リダイレクトの標準をpts
置き換えます。しかし、すべてのI / Oは別の場所(新しい疑似端末)であり、唯一のリンクはポート9999で始まったサーバーにあるため、何も起こらないようです。ここでは対話型スイッチは必要ありません。自動的に独自のLtd.になります。<>
bash
ncat
-i
bash
local $ ncat localhost 9999
[mikeserv@desktop ~]$ echo hey
echo hey
hey
[mikeserv@desktop ~]$ ls -l /dev/fd/[012]
ls -l /dev/fd/[012]
lrwx------ 1 mikeserv mikeserv 64 Dec 12 00:27 /dev/fd/0 -> /dev/pts/4
lrwx------ 1 mikeserv mikeserv 64 Dec 12 00:27 /dev/fd/1 -> /dev/pts/4
lrwx------ 1 mikeserv mikeserv 64 Dec 12 00:27 /dev/fd/2 -> /dev/pts/4
[mikeserv@desktop ~]$ ^[[A^[[A
今はほぼすべて来ました。したがって、私たちは間違いなくソケットをbash
持っていますが、そこには奇妙な二重エコーがあることがわかります。ここで問題は、2つのレベルの疑似端末があることです。私のクライアントが実行している擬似端末は、サーバーが実行されている擬似端末と同じにncat
設定されています。stty echo
そしてクライアントターミナルはライン指向であり、入力改行ごとに一度だけ出力をフラッシュし、デフォルト設定に応じstty echoctl
てctrl-charエスケープも印刷するので、bash
^ up矢印キーはまったく受信されず、面白いLittleエスケープだけを見ることができます。
わかりました、私たちもこの問題を処理できます。
local $ ncatsh()(
local > ${2+":"} set localhost "${1:?ncatsh(): No port number provided!}"
local > stty=" stty -F'$(tty)'" || unset stty
local > trap " ${stty- ncat '${1##*\'*}' '${2##*\'*}' </dev/null} \
local > ${stty+$(for a in -g 'raw -echo isig intr "^A" quit "" susp ""'
local > do eval "$stty $a";done)}
local > trap - 0 1 2; exit" 0 1 2
local > ncat "$@"
local > )
この関数は標準入力が端末(ローカル端末)であることを確認し、そうでない場合は入力をクライアントに渡しますncat
。しかしtrap
、もしそうなら出口、壊すと邪魔する信号は終了時に標準端子状態を再開します。これもいいことだから。変化ncat
標準を呼び出す前の状態です。
ローカルエコーが無効になっています。それ以外の場合、ローカル端末は次のように設定されます。生のモード - すべてのキーを押すとncat
すぐにサーバーに送信されます。実際、すべての特殊ローカルモードキーは無効になります。とは別に地元の整数- 通常CTRL+C
しかし、ここの構成は次のとおりです。CTRL+A
逆に - なぜならCTRL+C
bash
サーバーから解釈されます。
またやりたいのですがls
^上矢印を押してください。RETURN
。
local $ ncatsh 9999
[mikeserv@desktop ~]$ ls -l /dev/fd/[012]
lrwx------ 1 mikeserv mikeserv 64 Dec 12 01:00 /dev/fd/0 -> /dev/pts/4
lrwx------ 1 mikeserv mikeserv 64 Dec 12 01:00 /dev/fd/1 -> /dev/pts/4
lrwx------ 1 mikeserv mikeserv 64 Dec 12 01:00 /dev/fd/2 -> /dev/pts/4
[mikeserv@desktop ~]$ ^C
[mikeserv@desktop ~]$ ^C
[mikeserv@desktop ~]$ ^C
[mikeserv@desktop ~]$
local $
押すとローカルエコーがオフになるので、そこは見えませんでした。CTRL+A
セッションを中断し、すべてのローカル端末設定が正しい状態に復元されたローカルプロンプトに戻ります。しかし、サーバーはbash
まだそこにありncatsh 9999
、私が選択したらすぐに戻ってくるでしょう。
答え2
作業を簡素化するには、「netcat」ツールを試してください。サーバーまたはクライアントとして使用でき、任意のデータを送受信できます。
もしそうなら、低レベルのものを扱うことに気を付けないでください。
#server listening on port 8000/tcp
$>netcat -l 8000
#client sending stuff to localhost 8000/tcp
$>netcat localhost 8000
blah
答え3
bash
仮想/dev/tcp/host/port
ファイル(元のksh関数)は、次の場合にのみ使用できます。つながるTCPポートソケット。
リスニングソケットを作成し、それから受け入れソケットを作成するなど、より多くのことをしたい場合は、リダイレクトを使用して実行することはできません。
zsh
zsh/net/tcp
モジュールと組み込み機能によりこれをサポートしますztcp
。
zmodload zsh/net/tcp
handle-connection() (
IFS= read -ru4 line || exit
print -r "Got: $line"
print -ru4 "Hello $line"
ztcp -c 4
)
ztcp -l -d 3 1234 # create a TCP listening socket on port 1234 on fd 3
while ztcp -ad4 3 # accept connection on fd 4
do handle-connection & exec 4>&-
done
バインドするアドレスまたはリスニングキューのサイズを指定できない、1方向だけをオフにする、またはソケットオプションを設定できないという点で依然として制限されています。 UDPまたはSCTPも実行しません(できます)。コマンドを使用しますが、Unixドメインソケットインタフェースzsocket
)。
より高度な機能が必要な場合、またはzshがない場合socat
。bash
handle_connection() {
IFS= read -r line &&
printf 'Hello %s\n' "$line"
}
export -f handle_connection
socat tcp-listen:1234,reuseaddr,fork 'exec:bash -c handle_connection'
可能性はsocat
無関心です。詳しくはマニュアルページをご覧ください。
たとえば、サーバーにシェルセッションを作成させるには、次のようにします。
socat tcp-listen:1234,reuseaddr,fork exec:bash,pty,ctty,setsid,stderr,sane
クライアント側では、次のように接続できます。
socat -,raw,echo=0 tcp:host:1234
答え4
最も簡単な方法は、xinetd
次のように独自のサービスを作成することです。
/etc/services
:
...
foo 500/tcp
...
/etc/xinetd.d/foo
:
service foo
{
disable = no
bind = 127.0.0.1
socket_type = stream
protocol = tcp
log_on_failure += USERID
server = /usr/local/lib/foo.sh
user = il
instances = UNLIMITED
wait = no
log_on_success =
}
/usr/local/lib/foo.sh
:
read ...
...
echo ...
したがって、シェルスクリプトは各クライアント接続に対して実行され、stdin / stdoutをソケットに直接追加します。