サーバー上のnetcatに、送信されたばかりのファイルに対して機能するスクリプトを実行させ、このスクリプトの出力をクライアントへの応答として送信させたいと思います。私のアプローチは:
受信サイト:
nc.traditional -l -p 2030 -e "./execute.sh" > file.iso
送信サイト:
cat file.iso - | nc.traditional -w 1 serverAddress 2030
現在、受信サイトはファイルが完全に転送される前にスクリプトを実行しますが、スクリプトの出力を送信サイトに送信してから接続を閉じます。スクリプトを実行する前に、ファイルが完全に転送されるまで受信サイトに待機してもらいたい。
受信側が転送されたファイルの終わりを認識するための何らかの方法が必要です。送信側にcat file - | nc
を使用すると、パイプを介したデータストリームは、ファイルの内容とユーザーが端末で入力したものを区別しません(cat -
は端末を読み取ります)。また、デフォルトでは、netcatはEOFに反応しませんが、-q
を使用してEOFに沿って。
したがって、受信スクリプトは次のようになります。
#!/bin/bash
filename=$1
cat > "$filename"
hash=$(shasum "$filename" |sed -e 's/ .*//')
printf "received file \"%s\" with SHA-1 hash %s\n" "$filename" "$hash"
cat
はEOFまで入力を読み取り、ファイルを保存します。以下は何でも、ファイルが受信された後に実行されます。ここで、スクリプトは、受信したデータのSHA-256ハッシュを送り返します。
次に、受信側で次を実行します。
$ nc.traditional -l -p 12345 -c "./receivefile.sh somefilename"
送信側では:
$ cat sourcefile | nc.traditional -q 9999 localhost 12345
received file "somefilename" with SHA-1 hash 3e8a7989ab68c8ae4a9cb0d64de6b8e37a7a42e5
上記のスクリプトはファイル名を引数として取るため、-c
ではなく-e
を使用しましたが、nc
の出力を宛先ファイルにリダイレクトすることもできます。質問でした。
送信側からもファイル名を送信したい場合は、受信側で次のようにすることができます。
#!/bin/bash
read -r filename
[[ $filename = */* ]] && exit 1 # exit if the filename contains slashes
cat > "$filename"
echo "received $filename"
(echo filename; cat filename) | nc -q 9999 localhost 12345
で送信します。 (ここで、リモートから提供されるファイル名をより注意深くしたい場合があります。または、scp
などのファイル転送用に設計されたものを使用してください。)
nc
を使用する代わりに、SSHを使用してこれを同様に行うことができます。
cat filename | ssh user@somehost receive.sh