Paramikoでファイルのリストを表示する方法

PythonでParamikoを使って、 リモートサーバーのファイルのリストを表示する方法を紹介します。 リストを取得するにはlistdir()listdir_attr()の2つのメソッドがあるので順番に解説します。

サンプルの環境として、リストを取得するディレクトリは、 リモートサーバーのログインディレクトリの直下にある 「test」ディレクトリとします。 「test」ディレクトリには次のように2つのディレクトリ(dirA、dirB)と、 2つのファイル(file1.txt、file2.txt)があります。

test
├ dirA
├ dirB
├ file1.txt
└ file2.txt

listdir()によるファイルリスト取得

次のサンプルコードでは、 listdir()メソッドを使ってtestディレクトリのファイルリストを取得し、 forループで1つずつ表示しています。

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("test")

# ファイルリストを取得
files = sftp_con.listdir()

# 表示
for rfile in files:
	print(rfile)

# クローズ
client.close()
実行結果
file2.txt
file1.txt
dirB
dirA
このようにリストとして取得できます。
シンプルにリストを取得するだけならlistdir()でも十分ですが、 ファイルやディレクトリの区別をしたい場合はlistdir()だともの足りなくなります。 その場合は次に紹介するlistdir_attr()メソッドを使ってください。

listdir_attr()によるファイルリスト取得

次は、testディレクトリの内容をlistdir_attr()メソッドを使って取得してみます
(以後はSFTP接続の開始・終了部分のコードは省略)。

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

# ファイルリストを取得
files = sftp_con.listdir_attr()

# 表示
for rfile in files:
	print(rfile)
実行結果
-rw-r--r--   1 118130   1000            4 25 Nov 2020  file2.txt
-rw-r--r--   1 118130   1000           16 06 May 04:16 file1.txt
drwxr-xr-x   1 118130   1000         4096 19 May 10:47 dirB
drwxr-xr-x   1 118130   1000         4096 19 May 10:46 dirA

listdir_attr()で取得したリストをそのまま表示すると 上のように表示されます。 Linux上で「ls」コマンドを実行したような内容です。

リスト内容のプロパティと値を表示

リストの内容(rfile)自体がオブジェクトなので、 リスト(files)の先頭要素のプロパティと値を表示してみます。

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

# ファイルリストを取得
files = sftp_con.listdir_attr()

# 先頭要素を取得
objfile = files[0]

# プロパティと値を表示
for key, value in objfile.__dict__.items():
  print(key, value)
実行結果
_flags 15
st_size 4
st_uid 118130
st_gid 1000
st_mode 33188
st_atime 1652975413
st_mtime 1606282680
attr {}
filename file2.txt
longname -rw-r--r--    1 ユーザー名        4 Nov 25  2020 file2.txt

このように「st_size」や「st_uid」などの複数のプロパティがあります。
この中で必要なのは赤字部分の「st_mode」と「filename」です。

次はこの2つのプロパティを使ってディレクトリとファイルを 区別するロジックを記述します。

ディレクトリとファイルを区別する

st_mode」と「filename」を使って、 リストからディレクトリとファイルを区別します。

まずは先頭のimport部分にstatモジュールを追加してください。

import stat
import paramiko

statモジュールのS_ISREG()関数とS_ISDIR()関数を使います。
stat --- stat() の結果を解釈する — Python 3.10.4 ドキュメント

次にロジック部分です。S_ISREG()でファイルかどうかを判定し、 S_ISDIR()でディレクトリかどうかを判定します。 それぞれの関数の引数に「st_mode」を指定します。 ファイル名やディレクトリ名は「filename」で取得できます。

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

# ファイルリストを取得
files = sftp_con.listdir_attr()

# ファイルとディレクトリを区別
for rfile in files:

	if stat.S_ISREG(rfile.st_mode):
		print("file: " + rfile.filename)
	elif stat.S_ISDIR(rfile.st_mode):
		print("dir : " + rfile.filename)
	else:
		print("other")
実行結果
file: file2.txt
file: file1.txt
dir : dirB
dir : dirA

このようにファイルとディレクトリを区別し、 ファイル名・ディレクトリ名だけを取得することができました。

Python