LoginSignup
1
1

トラブル対応メモ:PHP画面から外部サーバへのファイル転送不良

Last updated at Posted at 2024-05-20

いつものように基本的知識の不足ゆえ、久々にドハマりしてしまったのでメモ。

(前提)

  • やりたいこと:PHPプログラム(Web画面)からexec関数を実行し、SCPを使って外部サーバへファイルをリネームしながら転送
  • SCPの実行に当たっては、本来は公開鍵方式でやるべきだが、相手先サーバの事情によりパスワード認証方式で実行せねばならない。
     ⇒シェルのexpectコマンドを使ってSCPを実行し、疑似対話イメージでパスワードを指定することにした。
expect -c "
set timeout 30
spawn /usr/bin/scp (転送元ディレクトリ)/hoge.txt root@(転送先サーバ):(転送先ディレクトリ)/hogefuga.txt
expect default { exit 10 }   \"root@(転送先サーバ)'s password: \"  ; send \"(転送先サーバパスワード)\n\"
interact
"

(発生した事象)

  • PHPプログラムを実行したところ、転送先サーバにリネーム後のファイルがコピーされない。
  • ただし、転送先にリネーム後と同名のファイルがあれば、正しく上書きされる。
  • 上記SCPコマンドをコマンドラインから実行すると、転送先の同名ファイルの有無にかかわらずリネーム後のファイルが正しくコピーされる。

当初はPHPの設定の問題かと、その近辺をあれこれ調べましたが、該当する要素は見つからず・・・

(原因)

  1. expectコマンド中のパスワード送信時の改行コードが誤っていました("\r"が正)。
  2. 何より、expectで指定しているコマンド中の"interact"が悪さしてた模様です。

manによれば、"interact"はプロセスの制御をユーザーに渡すコマンドのため、上記の例では標準入出力がシェルに戻ってしまうそうで。
それでリネームファイルがコピーできない原理は「?」なのですが:sweat_smile:、ともあれ望ましい姿にはすべきでしょう。
⇒対話形式シェルのソースをサンプルにして、よー調べんとコピーしたのがあかんかったようです・・・

(対応)

expectコマンドの内容を、(参考)のページを参考に修正し、結果正しくコピーできるようになりました。

expect -c "
set timeout 30
spawn /usr/bin/scp (転送元ディレクトリ)/hoge.txt root@(転送先サーバ):(転送先ディレクトリ)/hogefuga.txt
expect default { exit 10 }   \"root@(転送先サーバ)'s password: \"  ; send \"(転送先サーバパスワード)\n\"
expect {\"100%\" { exit 0}}
"

(参考)

シェル以外からexpectしててハマったメモ
※鬼のようにググっていたら、たまたまヒットしたのがラッキーでした

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1