はじめに
Windows には標準でコマンドライン FTP クライアント(ftp.exe)が入っており、
- 対話的にコマンドを叩いて検証
- バッチファイルで自動実行
といった用途に使えます。Microsoft のコマンドリファレンスにも ftp の構文(-s: でスクリプトを流す等)が掲載されています。
一方で、FTP は認証情報も含めて平文で流れるプロトコルであり、セキュリティ的には推奨されません。また、Windows 標準の ftp.exe はパッシブモード(PASV)非対応なため、NAT やファイアウォール配下などの環境では「接続はできるのに、ファイル転送が進まない」といった問題が起こりやすいです。
この記事では、
- まず「動かす」ための最短手順(対話モード)
- バッチによる自動化方法
- 実際にハマりがちなポイントと回避策
の順に整理します。
背景・ユースケース
こんなユースケースで「Windows の ftp コマンドをサクッと使いたい」ことがあります。
- 社内検証や一時的なファイル受け渡しで「GUI なしで FTP を叩きたい」
- 障害切り分けで「コマンドで再現してログを取りたい」
- **定期実行(タスクスケジューラ等)**のために「シンプルなスクリプトで自動化したい」
一方で、恒常的な運用や本番環境では、後述の通り SFTP/FTPS など暗号化された手段へ移行することを強く推奨します。
前提環境(想定)
- OS: Windows 10 / Windows 11
-
シェル: コマンドプロンプト(
cmd.exe) -
コマンド:
ftp.exe(Windows 標準クライアント)
ftp が見つからない場合や実行できない場合は、後述の「ハマりどころ」を参照してください。
結論(要点だけ知りたい人向け)
-
手動操作なら
ftp <host>→user/put/get/byeで基本操作は一通りできる -
自動化したいなら
ftp -n -s:<script> <host>が最短パターン -
標準
ftp.exeは PASV 非対応のため、- 接続できても
ls/put/getがタイムアウトすることがある - その場合は WinSCP / curl 等の PASV 対応クライアントに切り替える
- 接続できても
再現手順(最短:対話モードで1ファイル送受信)
ここでは「とりあえず 1 ファイルを送受信してみる」までの最短手順を示します。
1) 接続してログイン
コマンドプロンプトを開いて、次のように実行します。
ftp ftp.example.com
プロンプトが出たら、指示に従って ユーザー名・パスワードを入力します。
2) バイナリ転送に切り替え(重要)
ftp はデフォルトで テキストモード(ascii) になっている場合があり、
zip / 画像 / 実行ファイル などでは必ず バイナリモードに切り替える必要があります。
binary
これを忘れると、転送後のファイルが壊れる原因になります(特に zip / 画像 / .exe など)。
3) ファイル送信(アップロード)
ローカルとリモートのディレクトリをそれぞれ移動してから、put します。
lcd C:\path\to\local
cd /path/to/remote
put local.zip
-
lcd… ローカル側のカレントディレクトリ変更 -
cd… リモート側のカレントディレクトリ変更 -
put… ローカル → リモートへのアップロード (sendと同義)
4) ファイル受信(ダウンロード)
同様に、ローカルの保存先を指定して get します。
lcd C:\path\to\download
get remote.zip
-
get… リモート → ローカルへのダウンロード
5) 切断
作業が終わったら bye か quit で切断します。
bye
なぜ詰まりやすいのか(FTP/ftp.exe の技術的背景)
FTP の仕組み(制御用とデータ用の2つの接続)
FTP は
-
制御用接続(通常
21/TCP) - データ用接続(ポート番号が別)
の 2 種類の TCP 接続を使います。
この「データ用接続」の張り方が アクティブモード / パッシブモード で異なっており、
NAT やファイアウォール配下ではデータ用接続が通らずに ls / put / get が固まる・失敗することがあります。
Windows 標準 ftp.exe の制約
ftp.exeはアクティブ接続前提- パッシブモード(PASV)をサポートしていない
という制約があるため、モダンなネットワーク環境では
- 「接続は成功するがファイル転送で失敗する」
- 「
lsが返ってこない・タイムアウトする」
といった症状が出がちです。
セキュリティ面の注意
- FTP は ユーザー名・パスワードを含め全て平文で流れる プロトコル
- Microsoft もドキュメント上で、セキュリティ観点から FTP を推奨しない旨を記載
本番運用・機微情報の取り扱いには原則 FTP を使わない方針にした方が安全です。
よく使う ftp コマンド(対話モード)
対話モードで頻出のコマンドをまとめます。ftp 起動後に入力します。
open <host> # 接続(既にftpを起動している場合)
user <user> <pass> # ログイン(プロンプトで対話入力も可)
dir / ls # リモートディレクトリ一覧
cd <dir> # リモート側のカレントディレクトリ変更
lcd <dir> # ローカル側のカレントディレクトリ変更
pwd # リモートのカレントディレクトリ表示
binary # バイナリ転送モードに変更(超重要)
ascii # テキスト転送モード(必要なときのみ)
get <remote> [local] # ダウンロード
put <local> [remote] # アップロード(sendと同義)
mget <pattern> # 複数ファイルのダウンロード
mput <pattern> # 複数ファイルのアップロード
delete <file> # リモートファイル削除
mkdir <dir> # リモートディレクトリ作成
rmdir <dir> # リモートディレクトリ削除
quit / bye # 終了
ポイント
- バイナリファイルを扱う場合は最初に必ず
binaryを実行する - ローカル・リモートでディレクトリが別々に管理されるので、
cdとlcdを混同しない
自動化(バッチ実行):ftp -s でスクリプトを流す
基本構文
ftp には -s:<filename> オプションがあり、テキストファイルに書いたコマンドを順次実行できます。
ftp -n -s:ftp-script.txt ftp.example.com
-
-s:<filename>: 与えたファイルの内容をftpのコマンドとして実行 -
-n: 自動ログインしない(userコマンドをスクリプト内で呼ぶ前提)
注意: スクリプト内にパスワードを平文で書くことになるので、権限・保管方法に要注意です。可能なら後述の通り、FTP ではなく SFTP/FTPS へ切り替えることを検討してください。
1) スクリプトファイルを作る(例:ftp-script.txt)
例として、local.zip をアップロードするスクリプトを書きます。
user FTP_USER FTP_PASSWORD
binary
lcd C:\path\to\local
cd /path/to/remote
put local.zip
bye
このファイルを例えば C:\scripts\ftp-script.txt に保存します。
2) スクリプトを実行する
コマンドプロンプトから次のように実行します。
cd /d C:\scripts
ftp -n -s:ftp-script.txt ftp.example.com
必要に応じて 詳細表示やデバッグ出力もオンにできます。
ftp -n -v -d -s:ftp-script.txt ftp.example.com
-
-v: 詳細なメッセージを表示 -
-d: デバッグ情報を表示
検証:うまくいっているかの確認ポイント
1) 転送後にファイルサイズが一致しているか
対話モードの場合、リモート側のサイズは dir で確認できます。
dir
ローカル側はエクスプローラーや dir コマンド等で確認し、サイズが一致しているかチェックします。
2) バイナリモードを忘れていないか
-
zip/.exe/ 画像ファイルなどが「壊れて開けない」ときは
まずbinaryを実行したかを真っ先に疑います。 - スクリプト・対話どちらでも、最初に必ず
binaryを入れておくのがおすすめです。
3) 自動化のログを残す
定期実行や障害調査では、標準出力/標準エラーをログファイルにリダイレクトしておくと便利です。
ftp -n -s:ftp-script.txt ftp.example.com > ftp.log 2>&1
type ftp.log
- 失敗した場合、エラーメッセージや応答コードを後から追える
- タスクスケジューラから実行する場合も、この形にしておくとトラブルシュートしやすいです
(実際にはここにログ画面やエラー画面のスクリーンショットを載せると、Qiita 記事として親切です)
ハマりどころ(落とし穴と回避策)
1) 「接続できるのに ls / put / get で止まる・失敗する」
症状
-
ftp ftp.example.comは通る - しかし
ls/dir/put/getで固まる or タイムアウトする
原因候補
- NAT / ファイアウォール配下でパッシブモード(PASV)が必須
- しかし Windows 標準
ftp.exeは PASV 非対応のため、データ接続が確立できない
回避策
- クライアントを PASV 対応のツールに切り替える
- GUI: WinSCP / FileZilla など
- CLI:
curl、lftp等(Windows でも利用可)
- もしくはネットワーク機器側の設定を調整(FTP ALG 等)
→ ただし、これは運用/セキュリティポリシーに依存するため現実的でない場合も多いです
2) 転送したファイルが壊れる
症状
- 転送した
zipが展開できない - 画像が壊れて表示されない
-
.exeが実行できない
原因
- バイナリモード (
binary) に切り替え忘れ
回避策
- 対話操作・スクリプトどちらでも、冒頭で必ず
binaryを入れておく - テキストファイル以外はすべてバイナリ前提で考える
3) ftp が見つからない / 実行できない
確認コマンド
where ftp
ftp /?
ここでパスが出なかったり、認識されていません 的なメッセージが出る場合は、
- OS のエディション/ポリシーによる制限
- 一部コンポーネントが削除されている
- 端末のセキュリティポリシーで禁止されている
といった可能性があります。
回避策
- 端末ポリシー/グループポリシーを確認(企業環境の場合は情シスに確認)
- 代替ツール(WinSCP, curl, PowerShell の
Invoke-WebRequestなど)への切り替えを検討
4) パスワードをスクリプトに平文で置くのが怖い
ftp -s で自動化すると、どうしてもスクリプト内にパスワードを平文で書く形になりがちです。
- そもそも FTP 自体が平文プロトコル
- ネットワーク上でも端末上でも、認証情報が露出しやすい
回避策(根本的な方向性)
- 可能であれば FTP ではなく SFTP/FTPS を採用
- SFTP (SSH File Transfer Protocol)
- FTPS (FTP over TLS)
- 認証はできるだけ 鍵認証や証明書ベースに寄せる
- 標準
ftp.exeは SFTP 非対応のため、- WinSCP のコマンドライン
-
psftp(PuTTY) -
sftp(WSL や Git Bash などに含まれる場合あり)
といった 別ツールを前提に設計する方が安全です。
まとめ
-
Windows の
ftpコマンド (ftp.exe) は、対話操作と-s:オプションによる自動化に対応しており、簡易な検証や一時的なファイル受け渡しには便利です。 - ただし、標準
ftp.exeはパッシブモード(PASV)非対応であり、モダンなネットワーク環境では 接続は成功するのに転送が失敗するといった詰まりどころが多いです。 - セキュリティ面でも FTP は平文プロトコルであり推奨されないため、継続的な運用を考える場合は、暗号化された SFTP/FTPS + 対応クライアントへの移行を前提に設計しておくのが安全です。
「とりあえずコマンドで再現したい」「一時的にログを取りたい」といった場面では、本記事の手順を参考にしつつ、最終的な運用はより安全なプロトコルへ寄せていくことをおすすめします。