検索で調べようとすると結構めんどくてなこれ。検索ワードを苦心しないと DataFrame ばっかヒットする。そっちじゃのーて、れがしーな「df コマンド」ん話ばね。
Windows ではエクスプローラでディスク使用状態はわかる。Unix で伝統的なものが、ほぼ全ての Unix において組み込みコマンドとして提供される「df」で。Unix もどきであるところの MSYS にも含まれる:
1 [me@host: ~]$ df
2 Filesystem 1K-blocks Used Available Use% Mounted on
3 C:\Users\hhsprings\AppData\Local\Temp
4 975853100 213647480 762205620 22% /tmp
5 C:\MinGW\msys\1.0 975853100 213647480 762205620 22% /usr
6 C:\MinGW\msys\1.0 975853100 213647480 762205620 22% /
7 c:\MinGW 975853100 213647480 762205620 22% /mingw
8 c: 975853100 213647480 762205620 22% /c
9 df: `/d': no medium
10 e: 117218300 74057388 43160912 64% /e
11 f: 4883637932 564701368 4318936564 12% /f
12 g: 234428412 58487564 175940848 25% /g
13 h: 60604384 48458848 12145536 80% /h
14 [me@host: ~]$ df -h
15 Filesystem Size Used Avail Use% Mounted on
16 C:\Users\hhsprings\AppData\Local\Temp
17 931G 204G 727G 22% /tmp
18 C:\MinGW\msys\1.0 931G 204G 727G 22% /usr
19 C:\MinGW\msys\1.0 931G 204G 727G 22% /
20 c:\MinGW 931G 204G 727G 22% /mingw
21 c: 931G 204G 727G 22% /c
22 df: `/d': no medium
23 e: 112G 71G 42G 64% /e
24 f: 4.6T 539G 4.1T 12% /f
25 g: 224G 56G 168G 25% /g
26 h: 58G 47G 12G 80% /h
27 [me@host: ~]$ df -B M
28 Filesystem 1M-blocks Used Available Use% Mounted on
29 C:\Users\hhsprings\AppData\Local\Temp
30 952982M 208642M 744341M 22% /tmp
31 C:\MinGW\msys\1.0 952982M 208642M 744341M 22% /usr
32 C:\MinGW\msys\1.0 952982M 208642M 744341M 22% /
33 c:\MinGW 952982M 208642M 744341M 22% /mingw
34 c: 952982M 208642M 744341M 22% /c
35 df: `/d': no medium
36 e: 114471M 72322M 42150M 64% /e
37 f: 4769178M 551467M 4217712M 12% /f
38 g: 228934M 57117M 171818M 25% /g
39 h: 59184M 47331M 11854M 80% /h
まぁ日常的にはそのエクスプローラで見るか、ワタシの場合はこのように MSYS の df で事足りる、てわけなんだけれども。
まれに、長時間このディスク使用量を監視していたいことがあってね。今の場合は絶賛大量ファイル圧縮中、なんだけど、その効果・推移を観察していたい、てやつ。この場合、エクスプローラでは物足りなくて、df コマンドだと今ひとつ融通がきかない。たとえば「3.23 GB」みたいなのが読みやすくていいんだがなぁ、てニーズには df はこたえてくんないし、そもそもグラフにでもしたいなら…。
「ゆえに python で」、て話。「ワタシさえ良ければいい」の中でも最も極端な考え方を採る場合、ワタシは MSYS を持っているわけで、なので MSYS 付属の df を subprocess で呼び出して使うんでもいい、んだけれど、一応 python だけで出来るやり方で。結局は「ワタシさえ良ければいい」であることには変わりはないんだけどね。
python 3.3+ では簡単で:
1 Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
2 Type "help", "copyright", "credits" or "license" for more information.
3 >>> import shutil
4 >>> shutil.disk_usage("h:/")
5 usage(total=62058889216, used=49641783296, free=12417105920)
一応ワタシ個人の事情により一応 python 2.7 の話もしとくと、「3.3+」と言った通り 2.7 の shutil には disk_usage は含まれないので、ほかの手段を考える必要がある。
Windows のことを考えなくていいなら実は 2.7 だろうがなんだろうが「os.statvfs」がいつでも使えるが、Windows なのでね、ワタシが日常使っているのは。「標準添付モジュールで出来る範囲で」の(ctypes で Win32 API を直接叩く以外の)やり方は見つけてない。結局は psutil が救世主よね:
1 Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:25:05) [MSC v.1500 64 bit (AMD64)] on win32
2 Type "help", "copyright", "credits" or "license" for more information.
3 >>> import psutil
4 >>> psutil.disk_usage("h:/")
5 sdiskusage(total=62058889216L, used=49693163520L, free=12365725696L, percent=80.1)
6 >>> res = psutil.disk_usage("h:/")
7 >>> print("{:.2f} GB".format(res.free / (1024.**3)))
8 11.51 GB
グラフ…はまぁやりたくなったらそのうち。matplotlib の animation とか、tkinter を使うとかで、それなりのものは作れるけど、今日のワタシには不要なので。今日のワタシにとっては「11.51 GB」で存分に「よしよし」なの。今日のワタシに必要なコマンドライン:
1 [me@host: ~]$ while true ; do py -3 -c 'import psutil ; r = psutil.disk_usage("h:/") ; print("{:.2f} GB\t{:.1f} %".format(r.free/(1024.**3), 100 - r.percent))' ; sleep 90 ; done
2 11.78 GB 20.4 %
3 11.78 GB 20.4 %
4 11.77 GB 20.4 %
これでファイル圧縮が順調に進んでいることを眺めて喜ぶことができる。
見出しが「(がやることの一部)」としている理由であるところの「今日のワタシには不要」は、ちょっとあとで真剣に考えてもいいかと思ってる。df はマウントポイントを列挙して全部出力するよね。今日のワタシPCの場合は、「c:/、d:/~h:/」。今日ここまでやったのは、「h:/ の」と特定してその情報を取得することしか出来てない。ま、やりたくなったら、ね。(実はこの目的が主食だったら、「今日のワタシ」には df を subprocess で呼び出して使う方が手っ取り早かったりする。)
2021-03-17追記:
グラフ化について、「265-nize」の追記参照。
2021-03-26追記:
ついでというか。
psutil が如何に救世主なのか、てのは、以前「コンソールウィンドウのタイトルをセットする(Windows)」なんてので書いたことがあった。「コンソールウィンドウのタイトルをセットする」動機というのはそもそも、「ワタシ、今何を? どこで?」を識別したい、てことである。異論はないよね? そして「やっぱ Windows なのだよなおぬしは」てこと。
「ワタシ、今何を? どこで?」を簡単に調べる術はこれは Windows では超絶にめんどい。「コンソールウィンドウのタイトルをセットする(Windows)」に書いた通りの理由で、エンドユーザが日常使う道具も相当欠落している。Windows しか知らないならそんなに怒りを覚えないところだったんだけれど、Unix だとこれが恐ろしく簡単だから弱るわけよね。基本的にはコマンドラインツールとしては ps か top あたりに頼れば、ほとんど日常は足りる。
Windows XP あたりから少しずつマシになっているとはいえ、それでもなお「tasklist.exe」はあまりにも役不足、タスクマネージャ・パフォーマンスモニタでは欲しい情報が足りてない。SysInternals のプロセスエクスプローラは非常に優秀で使い勝手がいいものの、それでもまだ欲しいものが少し欠けている。
一番毎日欲しいのに手に入らないのが、「現在動作中のコマンドライン」なんだけど、これは Unix なら ps で冗長オプション MAX にするなりで簡単に見ることが出来る。top でも同じく。これと同じことを、MSYS に付属の ps が出来ないのが…、まぁ本当のところは一番の癇癪の種なのかも(msys2は未確認)。
「コンソール」と ffmpeg みたいなのが実は非常に相性悪くて、打ち込んだ複雑な ffmpeg コマンドラインはその冗長過ぎる ffmpeg 出力によりすぐに可視ビューポート外となり、つまり「スクロールバーを操作しないと打ち込んだコマンドラインを確認出来ない」ということになるのだが、まぁやってみればわかる通り、現実的にはスクロールバーの操作は不可能である。ので、まぁすぐに「オレ、何やってるんだっけ」がわからなくなる。Windows + MSYS 環境でもう一つ致命傷なのが、「Ctrl-Z」でジョブをサスペンド出来ないことで、Unix に似てるからこそイライラの種になる。それが出来さえすれば、いったんサスペンドして何を打ち込んだのか確認ののち再開なんてことも出来るんだけどね。
そういうわけで、こういうものを必要とするわけだ:
1 #! py -3
2 # -*- coding: utf-8 -*-
3 from __future__ import print_function
4 from __future__ import unicode_literals
5
6 import os
7 import sys
8 import psutil
9
10
11 if __name__ == '__main__':
12 import argparse
13 ap = argparse.ArgumentParser()
14 ap.add_argument("--cmdbasename", action="store_true")
15 ap.add_argument("--cwdbasename", action="store_true")
16 args = ap.parse_args()
17 for p in psutil.process_iter():
18 cmdl, pwd = [], ""
19 try:
20 cmdl = p.cmdline()
21 except Exception as e:
22 print(e, file=sys.stderr)
23 try:
24 pwd = p.cwd()
25 except Exception as e:
26 print(e, file=sys.stderr)
27 if not cmdl:
28 continue
29 if pwd and args.cwdbasename:
30 pwd = os.path.basename(pwd)
31 if args.cmdbasename:
32 cmdl[0] = os.path.basename(cmdl[0])
33 print(pwd, cmdl)
「自分で見繕わねばならぬ」というだけでそれなりには地獄とも言えるけれど、だけれども psutil なしでこれと同じことをやろうとするとどうなるか知っていると、まさにこれは「天国」。
2021-03-26 18:00追記:
「Windows だと超絶にめんどい」がうまく伝わらんかなぁと思ってたんだが、やっぱ psutil 自身のソースコードがわかりやすかなと。たとえば _psutil_linux.c と _psutil_windows.c の行数を比較するだけでも雰囲気がわかるんではないかと。
2021-03-27追記:
psutil に基づくglancesについて触れておいた。
2021-04-03追記:
「df はマウントポイントを列挙して全部出力する」について、psutil に「disk_partitions」があった:
1 >>> import psutil
2 >>> dps = psutil.disk_partitions()
3 >>> dps[0]
4 sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed', maxfile=255, maxpath=26
5 >>> dps[0].mountpoint
6 'C:\\'
7 >>> [p.mountpoint for p in dps]
8 ['C:\\', 'D:\\', 'E:\\', 'F:\\', 'G:\\', 'H:\\']
9 >>> [psutil.disk_usage(p.mountpoint) for p in dps]
10 Traceback (most recent call last):
11 File "<stdin>", line 1, in <module>
12 File "<stdin>", line 1, in <listcomp>
13 File "C:\Program Files\Python39\lib\site-packages\psutil\__init__.py", line 1995, in disk_usage
14 return _psplatform.disk_usage(path)
15 File "C:\Program Files\Python39\lib\site-packages\psutil\_pswindows.py", line 265, in disk_usage
16 total, free = cext.disk_usage(path)
17 PermissionError: [WinError 21] デバイスの準備ができていません。: 'D'
18 >>> [psutil.disk_usage(p.mountpoint).free for p in dps if p.fstype]
19 [799600259072, 44196773888, 4567875444736, 180163428352, 22662057984]
てわけで、curses も使って(Windows の場合は windows-curses 必要):
2021-04-09追記:
「pythonの」と言っているのでいわゆるトピック違いではあるんだけれど、根底にあるのは「欲しいものが手元にない、何かいい手はないか」ということだけなので、一応触れておく。
別件でちょっと「Windows での一番の救世主は実は PowerShell」てことを言ったのだが、その流れで「powershell cmdlet unix command equivalent」という検索をしたら、まさに「unix df -ht in powershell」もヒットした。まぁそりゃそーだわな。ワタシんちでやればこんなね:
1 Windows PowerShell
2 Copyright (C) Microsoft Corporation. All rights reserved.
3
4 新しいクロスプラットフォームの PowerShell をお試しください https://aka.ms/pscore6
5
6 PS C:\Windows\Temp> Get-PSDrive
7
8 Name Used (GB) Free (GB) Provider Root CurrentLocation
9 ---- --------- --------- -------- ---- ---------------
10 Alias Alias
11 C 195.57 735.07 FileSystem C:\ Windows\Temp
12 Cert Certificate \
13 D FileSystem D:\
14 E 70.63 41.16 FileSystem E:\
15 Env Environment
16 F 400.93 4256.47 FileSystem F:\
17 Function Function
18 G 55.78 167.79 FileSystem G:\
19 H 50.00 7.81 FileSystem H:\
20 HKCU Registry HKEY_CURRENT_USER
21 HKLM Registry HKEY_LOCAL_MACHINE
22 Variable Variable
23 WSMan WSMan
24
25
26 PS C:\Windows\Temp> help Get-PSDrive
27
28 名前
29 Get-PSDrive
30
31 構文
32 Get-PSDrive [[-Name] <string[]>] [<CommonParameters>]
33
34 Get-PSDrive [-LiteralName] <string[]> [<CommonParameters>]
35
36
37 エイリアス
38 gdr
39
40 ... (省略) ...
41
42
43 PS C:\Windows\Temp> gdr
44
45 Name Used (GB) Free (GB) Provider Root CurrentLocation
46 ---- --------- --------- -------- ---- ---------------
47 Alias Alias
48 C 195.57 735.07 FileSystem C:\ Windows\Temp
49 Cert Certificate \
50 D FileSystem D:\
51 E 70.63 41.16 FileSystem E:\
52 Env Environment
53 F 400.93 4256.47 FileSystem F:\
54 Function Function
55 G 55.78 167.79 FileSystem G:\
56 H 50.01 7.81 FileSystem H:\
57 HKCU Registry HKEY_CURRENT_USER
58 HKLM Registry HKEY_LOCAL_MACHINE
59 Variable Variable
60 WSMan WSMan
よくわからんものも出てる。レジストリのこれはなんなんだろうかね。まぁとにかく df に近いことは出来る、てことで。