はじめに
FTPでファイルを取得するとき、ホスト名やユーザー名、パスワードをコマンドへ直接書くと、シェルの履歴や共有した画面に残る可能性があります。AIへコマンドの作成を依頼する場合も、実際の認証情報をチャットへ貼る必要はありません。
Bashのreadを使えば、接続情報をターミナル上で対話入力し、そのシェル内の変数へ一時的に保存できます。特にread -sは入力文字を画面へ表示しないため、パスワード入力に向いています。
readの意味から、lftpへパスワードをコマンドライン引数として直接渡さない実行例まで解説します。readコマンドで一時変数を作る仕組み
readは、標準入力から受け取った文字列をBashの変数へ保存する組み込みコマンドです。次の3行をターミナルへ1行ずつ貼り付けて実行します。
read -rp "FTPホスト: " FTP_HOST
read -rp "ユーザー名: " FTP_USER
read -rsp "パスワード: " LFTP_PASSWORD
printf '\n'
各行を実行すると、FTPホスト:などの文字が表示され、その右側が入力待ちになります。コマンド自体を書き換えるのではなく、表示された場所へ値を入力してEnterを押します。
| 指定 | 意味 |
|---|---|
-p |
入力前に案内文を表示する |
-r |
バックスラッシュを特別扱いせず、そのまま読み取る |
-s |
入力した文字を画面へ表示しない |
FTP_HOSTなど |
入力値を保存する変数名 |
-sを付けたパスワード入力では、文字も*も表示されません。入力できていないように見えても、そのままパスワードを入力してEnterを押します。read -sは末尾で改行しないため、次のprintf '\n'で表示位置を整えています。
なぜコマンド履歴にパスワードが残りにくいのか
Bashの履歴には、通常、変数展開前のコマンド文字列が保存されます。そのため履歴に残るのは次のようなreadの行であり、対話中に入力したパスワードそのものではありません。
read -rsp "パスワード: " LFTP_PASSWORD
反対に、次のように実際のパスワードをコマンドへ直接書く方法は避けます。
# 実行しない例
lftp -u "example-user","actual-password" ftp.example.com
この形は履歴へ残るだけでなく、実行中のコマンドライン引数として参照される可能性があります。変数へ保存しても、lftp -u "$FTP_USER","$LFTP_PASSWORD"のようにパスワードを引数へ展開すれば、この問題は解決しません。
read -sは入力を画面へ表示しない機能です。パスワードを暗号化したり、安全な保管庫へ保存したりする機能ではありません。lftpへパスワードを直接書かずに渡す
lftpは、環境変数LFTP_PASSWORDと--env-passwordを組み合わせる方法を案内しています。readで作った変数を子プロセスのlftpから参照できるように、まずexportします。
export LFTP_PASSWORD
次にlftpを実行します。以下のftp.example.comやディレクトリは説明用です。実際のホスト名とパスは、契約先やFTPソフトの設定で確認してください。
lftp --env-password --user "$FTP_USER" "$FTP_HOST" -e '
set ftp:ssl-force true;
set ssl:verify-certificate true;
mirror --dry-run --verbose /www/example ./example;
bye
'
この例では、パスワードの値をlftpのコマンドライン引数へ入れていません。最初は--dry-runで転送予定だけを確認し、接続先、リモート側、ローカル側が正しいと確認できてから本番を実行します。
FTPSに対応するサーバーを想定しているため、TLS接続と証明書検証を有効にしています。契約先が指定する方式がSFTP、FTPS、FTPのどれかを先に確認してください。通常のFTPは通信が暗号化されないため、利用できる場合はSFTPまたはFTPSを優先します。
mirrorによる取得先の指定やGit管理まで進める場合は、lftpのmirrorでFTPサイトをローカル保存する詳しい手順も参考にしてください。
作業後は変数を削除する
転送が終わったら、現在のシェルから接続情報を削除します。
unset LFTP_PASSWORD FTP_USER FTP_HOST
unset後に変数が空か確認する場合は、パスワード自体を表示せず、設定の有無だけを確認します。
if [[ -z ${LFTP_PASSWORD+x} ]]; then
echo "LFTP_PASSWORDは削除されています"
fi
変数は、基本的にそのターミナルのシェルが終了すれば失われます。ただし、作業途中でecho "$LFTP_PASSWORD"、env、setなどを実行すると、画面やログへ値が出ることがあります。共有画面、AIチャット、チケット、スクリーンショットにも実値を貼らないでください。
readを使うときの注意点
- 変数名には用途が分かる名前を使い、
HOMEやPATHなど既存の重要な変数を上書きしない - パスワードを含む変数を不用意に
echoしない set ssl:verify-certificate noで証明書エラーを恒久的に回避しない- 共用PCや信頼できない端末では認証情報を扱わない
- 長期保存や自動実行には、権限を制限した認証情報ファイルや秘密情報管理サービスを検討する
環境変数も万能な保管方法ではありません。同じアカウントで動く処理や高い権限を持つ利用者から参照される可能性があります。今回の方法は、短時間の手動作業で履歴やコマンドライン引数への露出を減らすためのものです。
まとめ
Bashのreadを使うと、FTPの接続情報をターミナルで対話入力し、一時変数へ保存できます。-pは案内文、-rはバックスラッシュの保持、-sは入力文字を非表示にする指定です。
lftpでは、パスワードを-uの引数へ直接含めず、LFTP_PASSWORDと--env-passwordを使います。作業後はunsetで変数を削除し、実際の認証情報をコマンド、AIチャット、共有画面へ貼らない運用を徹底しましょう。


コメント