Paramikoでディレクトリ移動(chdir)の方法と注意点

PythonでParamikoを使ってディレクトリの移動をする方法と 注意点を解説します。

FTPサーバー側のディレクトリを移動する場合、 Paramikoのchdirメソッドを使用します。

書式
chdir(パス)

パスは絶対パスか相対パスで記述します。
参考までにParamikoドキュメントのchdirの一部を引用しておきます。

 chdir(path=None)

    Change the “current directory” of this SFTP session. 
    Since SFTP doesn’t really have the concept of a current working directory, 
    this is emulated by Paramiko. 

SFTP — Paramiko documentation

引用部分に書いてあるように、 chdirを実行しても実際にディレクトリを移動しているのではなく、 エミュレートしているだけなのは頭の片隅にいれておいてください。

では実際にchdirを使ったディレクトリ移動のサンプルコードを紹介します。

サンプルコード

chdir()メソッドとgetcwd()メソッドを使ったサンプルコードです。
getcwd()はカレントディレクトリを表示するメソッド、
ログインディレクトリは「/home/user」です。

import paramiko

# SFTP接続準備
config = {
	"host" : "サーバー名",
	"port" : ポート番号,
	"username" : "ユーザー名",
	"password"   : "パスワード"
}

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
client.connect(config['host'], 
               port = config['port'],
               username = config['username'],
               password = config['password'])

# SFTPセッション開始
sftp_con = client.open_sftp() 

# ------------------------------------------------
# カレントディレクトリ確認
print(sftp_con.getcwd())

# ディレクトリ移動
sftp_con.chdir("web/test")

# カレントディレクトリ確認
print(sftp_con.getcwd())
# ------------------------------------------------

# クローズ
client.close()
実行結果
None
/home/user/web/test

ログインディレクトリ 「/home/user」から、相対パスで「"web/test"」に移動したので、 getcwdメソッドの結果が「/home/user/web/test」と表示されています。

最初のgetcwdメソッドの結果が「None」なのはgetcwdの仕様です。 一度chdirメソッドを実行しない限りはNoneが戻ります。

存在しないディレクトリを指定した場合

chdirメソッドの引数に、存在しないディレクトリを指定した場合は IOErrorが発生してプログラムが中断します。 中断しないようにtry文を使って例外処理を書いておく方が安全です。

次のコードはtry文を使った例外処理のサンプルコードです。 接続(open)や終了(close)部分は省略しています。 chdirに指定した「"hoge"」ディレクトリは存在しません。

try:
	# ディレクトリ移動
	sftp_con.chdir("hoge")

	# カレントディレクトリ確認
	print(sftp_con.getcwd())

except Exception as e:
	print(e)
実行結果
[Errno 2] No such file

exec_commandで「pwd」コマンドを実行してみる

実験として、ディレクトリを移動した後に 「SFTPClient.getcwd()」メソッドと 「Client.exec_command("pwd")」の両方を実行して違いを見てみます。
「pwd」コマンドはUnix(Linux)のコマンドで、カレントディレクトリを表示します。 Print Working Directoryの略です。

どちらもカレントディレクトリを表示するメソッドとコマンドですが、 表示結果が同じなのか違うのかに注目してください。

import paramiko

# SFTP接続準備
config = {
	"host" : "サーバー名",
	"port" : ポート番号,
	"username" : "ユーザー名",
	"password"   : "パスワード"
}

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
client.connect(config['host'], 
               port = config['port'],
               username = config['username'],
               password = config['password'])

# SFTPセッション開始
sftp_con = client.open_sftp() 

# -----------------------------------------------
# ディレクトリ移動
sftp_con.chdir("web/test")

# カレントディレクトリ確認
print("getcwd: " + sftp_con.getcwd())

# pwdコマンド実行
(stdin, stdout, stderr) = client.exec_command("pwd")
print("pwd   : " + stdout.read().decode('utf-8'))
# ------------------------------------------------

# クローズ
client.close()
実行結果
getcwd: /home/user/web/test
pwd   : /home/user

実行結果を見てみると、両者の結果は異なっています。 このことからもchdir()は実際に移動するわけではなく、 エミュレートしているだけなのがわかります。

Python