質問: ### 前提・実現したいこと シェルスクリプトで確実に、特定のリモートディレクトリ内へ、ファイルをFTP転送したいです。 ローカルディレクトリにある1つのファイル(piyo.txt)を、 リモートディレクトリ(/home/remoteuser/tmp/niwatori/.)へftp転送したいです。 ftpコマンドはシェルスクリプト内でbatモード実行し、結果をログにリダイレクトします。 `$ ftp -v -n < ftp_cmd.bat > ftp_cmd.result` ↓ftpバッチファイルの中身 ``` $ cat ftp_cmd.bat open 192.168.123.123 username passwd123 lcd /home/localuser/tmp/ mkdir /home/remoteuser/tmp/niwatori←★なかったときのため、リモートディレクトリniwatoriを作成する cd /home/remoteuser/tmp/niwatori←★リモートディレクトリniwatoriに移動し put piyo.txt←★目的のpiyo.txtをputする bye ``` ### 発生している問題・エラーメッセージ しかし、ここで問題が発生しました。 上記の処理の場合、niwatoriディレクトリ作成に失敗した場合はcdできず、(同名のファイルniwatoriが存在する場合はmkdirできない) リモートカレントにファイルをそのままputしてしまいます。 下記、(batファイルモードではありませんが)ftpコマンド失敗例↓ ``` $ ftp ftp> open 192.168.123.123 Connected to 192.168.123.123 (192.168.123.123). 220 (vsFTPd 3.0.3) Name (192.168.123.123:localuser123): remoteuser123 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> ftp> cd tmp 250 Directory successfully changed. ftp> ftp> mkdir niwatori 550 Create directory operation failed.←★同名のファイル"niwatori"が存在したので、550ステータスになってしまう ftp> ftp> cd niwatori 550 Failed to change directory.←★niwatoriファイルが既存であり、ディレクトリを作成できなかったため、cdできず550ステータス ftp> ftp> put piyo.txt local: piyo.txt remote: piyo.txt←★cdに失敗したので、niwatoriディレクトリでなくカレントディレクトリにputしてしまっている 227 Entering Passive Mode (192,168,123,123,126,37). 150 Ok to send data. 226 Transfer complete.←★転送自体は成功の226ステータス ftp> ftp> bye 221 Goodbye. ``` このような具合です。 ●これからもできないこと 運用でカバーはできません。 最初からリモートにniwatoriディレクトリを作成したり、 niwatoriという名前のファイル作成を禁じることはできません。 batファイルを2つに分ける、ftpコマンド以外(sshなど)を使用もできません。 ●できること FTP実行結果ログ(ftp_cmd.result)をリダイレクトで取得していますので、 これを解析してシェルスクリプトでif判定することは可能です。(現状、そうする予定です。↓に続く ●いま考えている案 いまのところ、ftp結果ログをシェルスクリプト上でgrepなどで解析し、 「cdできたかどうか("550 Failed to change directory."の文言が存在したら、cdできなかったとして異常終了とする)」で判断するしかないかな??と思っています。 ログ解析よりスマートな方法をご存じの方、アイデアをお持ちの方、 どうかお知恵を貸していただけませんでしょうか。 よろしくお願いします。 ### 補足情報(FW/ツールのバージョンなど) CentOS7 bash
回答: わたしなら、失敗する可能性のあるものと、失敗しないものと分けます。 ディレクトリを作成だけ行う処理と、ファイルを転送だけする処理にわけ、 無条件に2つの処理を行うことで、前者が失敗しても、後者は問題なく 処理を行うことができます。 ただ、もっと言うと、今時ftpではなくscpなりssh commandを利用した 処理に置き換えると思います。