
シリアル コンソール (ターミナル サーバー経由の Telnet など) しかない場合、ホストとの間でファイルを転送するにはどのような方法を使用できますか?
カット アンド ペーストは小さい/印刷可能なものには有効で、印刷不可能なものを処理するために uuencode/uudecode (gzip 付き) の組み合わせを試してみましたが、すべて非常に制限があります。
答え1
接続のもう一方の端で使用するシリアル コンソール プログラム¹ には、リモート側にファイルを送信する何らかの方法があります。 具体的な方法は、リモート システムで利用できるリソースによって異なります。
リモート側lrzsz
にあるkermit
最も簡単なケースは、リモート側に次のような堅牢なバイナリファイル転送プログラムがインストールされている場合です。lrzsz
またはkermit
これはかつては今日よりも一般的でしたが、特定のシステムではまだこれらのいずれかが残っている可能性があります。
ローカル側で使用しているシリアル コンソール プログラムには、Zmodem または Kermit アップロードを実行する方法がほぼ確実に備わっており、必要なものを直接送信できます。
Zmodem の場合は、rz
リモート システムに入力するだけで、ローカル シリアル ターミナルが理解できる特殊な文字列が送信され、ファイル ピッカー ダイアログがポップアップ表示されます。
Kermit はよりシンプルなプロトコルなので、その場合は手動で転送を開始する必要があります。
バイナリファイル転送プログラムはありませんが、uuencode
/base64
lrzsz
やのような適切なバイナリファイル転送プログラムを使用するとkermit
、効率、チェックサム、自動再試行、中断された転送の再開、複数ファイル転送など、いくつかの利点がありますが、これらは贅沢品送信するファイルが 1 つだけの場合、またはファイルをめったに送信しない場合は、ASCII アップロードで十分です。
なぜなら端末プロトコルバイナリデータファイル内のバイト値の多くを解釈できないため、同じ接続を介してファイルを直接送信することはできません。そうすると、どちらかの端末エミュレーションコードがデータの一部を解釈しようとし、データが破損し、混乱する端末処理コードも同様です。
これを回避するには、ローカル側でバイナリデータを安全なASCIIのサブセットにエンコードし、リモート側で生のバイナリデータに戻します。これがuuencode
そしてbase64
プログラムは、わずかなアルゴリズムの選択が異なるだけで、すべて同じです。
ローカルシステムでは、ファイルを次のようにエンコードします:²
$ uuencode -o sbf.uue some-binary-file.gz some-binary-file.gz
次に、リモート システムでこのコマンドを入力し、ローカル シリアル コンソールの「ASCII アップロード」機能を使用してファイルを送信します。
$ cat | uudecode
ファイルのアップロードが完了したら、 を押してCtrl-Cを終了しますcat
。これで、希望どおりに、リモート システムにデコードされたファイルが作成されます。
しかし私は多くの送信するファイルと印刷可能な ASCII トランスコーディングは面倒です。
より高いレベルの技術に自力で到達するのは難しくありません。リモート システムに C コンパイラがある場合は、前述のテクニックを使用してソースlrzsz
コードのコピーをリモート システムに送信できます。ローカル側では次のようになります。
$ uuencode -o lrzsz.tgz.uue lrzsz-0.12.20.tar.gz lrzsz-0.12.20.tar.gz
次に、リモート システムで、シリアル コンソール プログラムを使用して次のように入力します。
$ cat | uudecode
^C
$ tar xvf lrzsz-0.12.20.tar.gz
...build lrzsz normally
最初のコマンドを開始した後、lrzsz.tgz.uue
ファイルをリモート システムに「ASCII アップロード」します。パイプラインは uuencode されたデータを受け入れ、それをバイナリ tarball にデコードします。このバイナリ tarball は解凍してビルドできます。
しかし、リモートシステムにはCコンパイラがありません
リモートシステムにコンパイラがない場合でも、クロスコンパイルローカル システム上のプログラムrz
(またはその他のプログラム) を作成し、上記の手法を使用してリモート システムに送信します。
脚注:
ミニコム、ピココム、パテ、ヴァンダイク CRT...
このバージョンの には、入力ファイル名を
uuencode
2 回指定する必要があります。1 回は入力データのソースに名前を付けるため、もう 1 回は、データを出力ファイルにデコードするときにリモート システムがファイルを呼び出す名前を宣言するためです。リモート システムの出力ファイルに別の名前を付ける必要がある場合もあります。のローカル バージョンでは
uuencode
動作が異なる場合があります。
答え2
基本的に、シリアル tty 経由で転送するにはインターネット以前の方法を使用する必要があり、相手側で転送を受信する方法が必要です。明らかに、これを行う最良の方法は ZMODEM を使用することですが、これはsz
受信側にすでにツールが存在している必要があることを意味します。ただし、受信先がネットワークのないルーターである場合など、これは常に可能であるとは限りません。
この転送を実行する唯一の方法は、8 ビット以前のクリーン スタイルで、端末セーフ ASCII を使用してチャネル経由で直接転送することです。私は、ほとんどのシステムにインストールされていると思われる、より最新のツールを使用します。
送信者:
まずファイルをエンコードします
base64 file.tar.gz > file.tar.gz.b64
ここで、com send-fileコマンドがascii-xfr
、これが私の接続コマンドラインであることを確認してください。
picocom -f n -p n -d 8 -b 115200 --send-cmd "ascii-xfr -snv" /dev/ttyS0
通常はascii-xfr
受信側でこれが必要ですが、受信側がない場合は、-n
正しい行末を維持することでこれを回避します。
受信者:
接続が完了したら、受信したファイルを保存するディレクトリに移動します。
cd /tmp/
cat > file.tar.gz.b64
ピココムでは、私はただCtrl+a+s キー、送信するファイルのフルパスを入力します。転送が完了したら、Ctrl+C キーそれを破るためにcat
。
ファイルをデコードします。
base64 -d file.tar.gz.b64 > file.tar.gz
ASCII 転送にはチェックサム保護がないため、ファイルが送信したものと完全に同一であることを確認するために、できる限りのことを行ってください。私の受信ボックスにはチェックサム保護がありましたsha512sum
が、どのチェックサム コマンドでも十分です。合計が一致することを手動で確認したら、転送は成功したとみなすことができます。
答え3
シリアル コンソールしか持っていない場合にこれが機能するかどうかはわかりませんが、ネットワーク アクセスがある場合は、nc(1)
TCP/IP を使用してファイルをコピーできます。
# WARNING: Depending on your setup, this could make your system unbootable
[email protected] # nc -l 8675 | dd of=/dev/sdXXX
[email protected] # dd if=/dev/sdYYY | nc destination-box.local 8675
上記の例では、sdbYYY
ソース ボックスからsdaXXX
宛先ボックスにクローンを作成しました。TCP ポート番号として 8675 を選択したのは任意です。アクセスできる任意のポートを使用できます。また、デバイスである必要はなく、任意のファイルを使用できます。
[email protected] $ nc -l 12345 >> ~/.ssh/authorized_keys
[email protected] $ cat ~/.ssh/id_rsa.pub | nc destination-box.local 12345
2 番目の例では、rsa 公開キー ( ~/.ssh/id_rsa.pub
) をコピーし、それをターゲット ホストの承認済みキー ファイルに追加しました。
答え4
私は使うだろうカーミット、ファイル転送プログラムの祖先です。Linux が登場するずっと前から、私たちはそれを使用していました。