LinuxからWindows共有フォルダをマウントする

LinuxからWindows共有フォルダ、というかSMBサーバにアクセスできると便利ですよね。
最近はUbuntuなどのよく使われているディストリビューションなら、バンドルされているファイラが標準で
サポートしていたりしますが、今回はコマンドラインからマウントすることにします。

もくじ:

UbuntuからWindows共有フォルダをマウントする

Windowsユーザにはあまり馴染みのないフォルダマウント。ファイルシステムの機能で、この場合はファイルサーバ上にある特定のWindows共有フォルダを、あたかもローカルのディレクトリ以下に存在するようにリンクさせることができます。
一旦マウントすると、以降はローカルのパスを指定してファイルサーバにある共有フォルダを操作できます。

準備

だいたいのディストリビューションならmountコマンドが使えますが、Windows共有フォルダ(SMB)を扱う場合には追加のセットアップが必要だと思います。

下記はUbuntuでの例です。

マウント

マウントするには、mountコマンドに-t cifsオプションをつけて実行します。

この例では、ファイルサーバ側のパスが//smbserver/shared/dirで、ローカルの/mnt/tmpディレクトリ(既存のもの)にマウントしています。
コマンドの実行には管理者権限が必要です。

ファイルサーバ側でアクセス管理がされている場合は上記のようにアカウントを指定します。この例ではユーザ名USER、パスワードPASSWORDを使って接続しています。

リモートのパスとローカルパスが同じディレクトリを指すことになるので、この例では/mnt/tmpディレクトリ以下に、//smbserver/shared/dirディレクトリの中身(下位のファイルおよびサブディレクトリ)が接続されます。

接続先のWindowsによっては、SMBのバージョンを選ぶ場合があります。デフォルト値はSMBv1のようなので、最近のバージョンが接続先だった場合、IO Errorになることがあります。その場合はversオプションでクライアント側のバージョンを指定することで解決するかもしれません。
Windows 7ならvers=2.1、Windows 10ならvers=3.0を使うとうまくいくかも。

また、日本語のパスが文字化けする場合はiocharsetを指定してみて下さい。近頃の環境ならUTF-8で問題ないはず。これも最近の環境では指定しない場合IO Errorを出したことがありました。

ただ、私が試した環境ではUTF-8を使うのに必要な共有ライブラリが見つからない旨のエラーが出たので、パッケージを入れなおしたら解決しました。

アンマウント

不要になった場合はマウントを解除(アンマウント)しておきましょう。
アンマウントする際はumountコマンドにローカルのパスを指定します。

こちらも管理者権限が必要です。

Pythonで自動化する

単純に外部プロセスとして呼び出す程度で良ければ、Pythonで上記のマウントを自動化できます。
スクリプト例はこんな感じ。

以下、簡単に詳細を書いておきます。

マウント(subprocess)

基本はsubprocessモジュールでmountコマンドを実行するだけです。

ファイルサーバにアクセスする際のパスワードはgetpassモジュールを使ってスクリプト実行時に入力させます。
アンマウントするときもやり方は同じですが、すぐ操作するとビジーになっていることがあるため、マウント・アンマウントの前後でスリープtime.sleep()を入れています。

コピー(shutil)

ローカルのファイルシステムを扱うときと同じように、shutilモジュールを使ってディレクトリをまるごとコピーしています。
ローカルのあるディレクトリを指定し、同じ名前でマウント先にコピーしていますが、ファイルサーバ上のリモートパスがマウントされているので、特にファイルサーバであることを意識せずに操作できるという寸法です。

shutil.copytree()では、コピー先に存在しないディレクトリを指定する仕様なので、実行時に親ディレクトリまで作っておきます。

おわり。