Unix から操作する Windows 共有とのファイル転送

Unix と Windows の間でファイルを移動させること自体はよくある話であろう。Windows 側から移動させるのであれば、Samba の共有を利用して Unix にファイルを置いたり吸い出したりできる。

あるいは Unix 側に ssh が入っていて、Windows 側に Cygwin が入っていれば、Windows 側で scp コマンドを使うと簡単にコピーができる。

% scp -r username@unix-machine:/path/to/files /destination/path/
ここで-rは Recursive (再帰的) なので、指定したパス以下の全部のファイルをコピー先パスの下に転送してくれる。-C も指定すれば gzip で圧縮してくれる。

バックアップ目的だと tar を使うとよりいい(scp だと所有ユーザー名、シンボリックリンクなどがうまくコピーされない)。

% ssh -l username unix-machine "(cd /path/to ; tar zcf - files)" | (cd /destination/path ; tar zxvf -)
これは上のものと等価である。tar で z オプション(圧縮)が使えなければ2つともはずすといい。

しかし、Unix 側から操作したいことがたまにないだろうか。外から Unix マシンにログインして、電源が入りっぱなしのはずの Windows マシンとファイルをやりとりしたい場合もけっこうある。しかし、いちばん困るのはバックアップ目的の場合である。最近の Windows マシンはディスク容量が余っているから Unix のバックアップをおいておきたいのだが、root 権限は直接 ssh から使えないので、上のような方法が使えない。もちろん、いったん tar ファイルとしてどこかにおいてやればいいのだが、バックアップ目的だとそんなディスク容量があまっていないことのほうが多い。また、逆に Windows のファイルを Unix 上にバックアップしたいときも、できれば cron を使って定期的にやりたいと思うこともあるだろう。

そんなときに、Unix から Windows 共有とファイルをやりとりする方法がある。Samba をインストールしていれば、smbclient というプログラムがインストールされているはずだ(path が通っていないかもしれないので慎重に探すべし。/usr/local/samba/bin か /usr/samba/bin にありそう)。

% smbclient //windowsserver/share -U username
とやってみると、パスワードを聞かれた後、smb プロンプトが出るはずだ(出ない場合はサーバー名の名前解決がうまくいっていないので -I 123.45.67.89 の形式で IP アドレスを直接指定すべし。名前解決問題は複雑なので今回は割愛)。 これは ftp クライアントとほぼ同様に操作できるので、ls などとやってみると向こうのファイル一覧が見えるし、cd でディレクトリ変更して put や get でファイルのやりとりができるし、もちろん mget や mput もできるし prompt コマンドで問い合わせのありなしを切り替えられる。

さらに強力なのが、この smbclient は tar 形式と標準入出力に対応しているという点であろう。次のような形式で、Windows と Unix 間のファイル転送が可能だ。

# Windows の指定ディレクトリ以下を Unix 側に hoge.tar.gz として出力
smbclient //windowsserver/share -D sub/dir -U username -Tc - | gzip -9 -c >hoge.tar.gz

# Unix 側の hoge.tar.gz を Windows の指定ディレクトリに展開
zcat hoge.tar.gz | smbclient //windowsserver/share -D sub/dir -U username -Tx -

# Unix 側の指定ディレクトリ以下を Windows 側に sub/dir/hoge.tar.gz として出力
(cd /path/to ; tar czf - files) | smbclient //windowsserver/share -U username -c "put - sub/dir/hoge.tar.gz"

# Windows 側の sub/dir/hoge.tar.gz を Unix 側の指定ディレクトリに展開
smbclient //windowsserver/share -U username -c "get sub/dir/hoge.tar.gz -" | (cd /path/to ; tar zxf -)

# Unix 側の指定ディレクトリ以下を Windows 側にそのまま転送
(cd /path/to ; tar cf - files) | smbclient //windowsserver/share -D sub/dir -U username -Tx -

# Windows 側の指定ディレクトリ以下を Unix 側にそのまま転送
smbclient //windowsserver/share -D sub/dir -U username -Tc - | (cd /path/to/files ; tar xf - files)
上のコマンドちゃんと検証していないのだが、基本的にこのような形で使えるはずだ。

ここでは書かなかったが、smbclient にはほかにもさまざまな機能がある。パスワードもコマンドライン (-U username%password でいい) や環境変数や別ファイルで指定できるし、さらには Windows 側のファイルに関して日付や Archive Bit を利用した増分バックアップ、WinPopup を利用した Windows 画面へのメッセージ表示 (!)、Windows 共有されたプリンタへの印刷 (非 PS プリンタに PostScript は送れないが)、細かいところではファイル名の小文字化、正規表現でのファイル名指定、など、本当にさまざまなことが実現されている。 なんと強力なのだろうか! これさえ使えればあなたも Samba マニアとして一部の人から怪しまれること間違いない(謎)。

※ 2004/2/26 追記: もし root 権限があるのなら smbfs とか cifs を直接マウントできるよう設定するほうがらくだと思います。しかし、root 権限がない場合、smbclient の便利さは捨てがたいです。