質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Q&A

解決済

1回答

1566閲覧

expectでsftp接続してディレクトリが見つからない場合ディレクトリを作成する方法について。

ac130

総合スコア2

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

0グッド

0クリップ

投稿2023/05/29 07:25

お世話になります。

前提

OS:ローカルリモート先共にCentOS7
expect version 5.45

シェルスクリプトにてexpectを用いて以下ような仕組みを作ろうと思っています。
1.sftp接続を行う。
2.リモート先でディレクトリの存在チェックを行う。
3.リモート先でディレクトリが存在しない場合は、リモート先でディレクトリの作成を行う。

ソースコード

shell

1#!/bin/bash 2 3DIR_PATH=$1 4 5expect -c " 6set timeout 30 7 8#sftpコマンドを叩く 9spawn sftp hoge@000.000.00.000 10 11expect { 12 default {exit 2} 13 \"continue connecting (yes/no)?\" {send \"yes\r\"; exp_continue} 14 \"assword\" 15} 16 17send \"hogehoge\r\" 18expect { 19 timeout {exit 2} 20 \"Permission denied\" {exit 2} 21 \"sftp>\" 22} 23 24send \"ls ${DIR_PATH}\r\" 25expect { 26 timeout {exit 2} 27 \"not found\" {send \"mkdir ${DIR_PATH}\r\"; exp_continue} 28 #\"not found\" {exit 3} 29 \"sftp>\" 30} 31 32#接続を閉じ終了する 33send \"quit\r\" 34exit 0 35" 36 37#結果を出力 38echo $?

発生している問題

ディレクトリの存在チェックはlsコマンドを用いて判断しています。
「not found」が返ってきたら存在しないと判断して
mkdirコマンドでディレクトリの作成を行うつもりなのですが、
現在思ったようにmkdirコマンドが実行されません。

shell

1expect { 2 timeout {exit 2} 3 \"not found\" {send \"mkdir ${DIR_PATH}\r\"; exp_continue} ←これが実行されない。 4 #\"not found\" {exit 3} ←sendを止めてexitにすると実行される。 5 \"sftp>\" 6}

恐らくsendの指定方法が間違っているのだと思うのですが、調べても分からず質問させて頂きました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2023/05/29 11:59

出力はどうなってますか?sftpの出力が見えるはずですが。
ac130

2023/05/30 00:16

コメント頂きありがとうございます。 出力は以下の通りです。※引数に/home/hoge/testを渡しています。 spawn sftp hoge@000.000.00.000 hoge@000.000.00.000's password: Connected to 000.000.00.000. sftp> ls /home/hoge/test Can't ls: "/home/hoge/test" not found sftp> 0 send mkdir部分をexit 3に置き換えると以下の通り3が返ってきます。 spawn sftp hoge@000.000.00.000 hoge@000.000.00.000's password: Connected to 000.000.00.000. sftp> ls /home/hoge/test Can't ls: "/home/hoge/test" not found sftp> 3 よって、send mkdir部分が正しくないのだと考えています。
guest

回答1

0

ベストアンサー

not foundだけ見て、sftp>を待たずに送信しているからだと思います。
\"not found\rsftp>\"\"not found\nsftp>\"\"not found\r\nsftp>\"ではマッチしなかったので、正規表現で文字クラスを使うと何故か成功。よくわからない。

expect

1expect { 2 timeout {exit 2} 3 -re \"not found\[\r\n\]*sftp>\" {send \"mkdir ${DIR_PATH}\r\"; exp_continue} 4 #\"not found\" {exit 3} 5 \"sftp>\" 6}

投稿2023/05/30 09:04

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ac130

2023/05/31 00:37

回答頂きありがとうございます。 お教え頂いた方法で正しく動作しました。 複数行に対して照合ができるのですね。 大変勉強になりました。 >not foundだけ見て、sftp>を待たずに送信しているからだと思います。 こちら実は試したことがあって、 以下で対応できないか試したのですが、上手くいきませんでした。 ※この書き方でもsendを止めてexitにするとexit 3が実行されます。 expect { \"not found\" { expect \"sftp> \" send \"mkdir ${DIR_PATH}\r\" #exit 3 } \"sftp> \" } まだexpectについて理解できていない所はありますが、 とりあえずはお教えいただいた方法で対応します。 ありがとうございました。
otn

2023/05/31 04:56

> 以下で対応できないか試したのですが、 最初、複数行の対応がうまく行かず、お書きのとほぼ同じの2段構成もやってみたのですが、 ケース1: not foundが出て内側のexpect実行後に sftp> がでて待つのに成功 ケース2: not foundが出てすぐにsftp>がでるので、内側のexpectがsftp>を待とうとしても出た後なのですでに遅い の2パターンがあるようで、うまく行ったり行かなかったりですね。 ケース2の場合はタイムアウトしますので、ちょっと現象が違う気もしますが。 複数行を待つのが駄目なら、not found 検出後に1秒待つような手段しかないかと思いかけました。
ac130

2023/06/01 05:42

なるほど。 一行の照合では確実性に欠けるようですね。 可能な限りお教えいただいた複数行の照合を行う様にしようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問