• ベストアンサー

自動パスワード入力でscpするスクリプトでエラー「Unterminated quoted string」

Win2kのCygwinで下記のスクリプトを試してみました。 (ローカルのファイルをscpで自動転送) $ uname -a CYGWIN_NT-5.0 upsil 1.5.11(0.116/4/2) 2004-09-04 23:17 i686 unknown unknown Cygwin $ cat ./test.sh #!/bin/sh HOST=192.168.1.105 # scp するマシン名を設定 UNAME=user01 # ログイン名を設定 PASSWD=xxxxxxxx # パスワ-ドを設定 TARGET=/cygdrive/c/cygwin/home/root/hoge /usr/bin/zip -r $TARGET.lzh $TARGET expect -c " # expect コマンドを実行 set timeout 20 spawn scp -P 60001 $TARGET.lzh $UNAME@$HOST:/home/fat32/ # expect コマンドの管理下でscpを実行する expect login:\ ; send \"$UNAME\r\" # login: が出たらログイン名を打ち込む expect sword:\ ; send \"$PASSWD\r\" # password: が出たらパスワ-ドを打ち込む #expect \"$\" ; send \"ls\r\" # $ が出たら ls を打ち込む #expect \"$\" ; send \"exit\r\" # $ が出たら exit を打ち込む $ which expect /usr/bin/expect $ which zip /usr/bin/zip $ ./test.sh と実行すると : 9: Syntax error: Unterminated quoted string となり、終ってしまいました。 「expect -c " # expect コマンドを実行」 が問題みたいなのですが何がまずかったのでしょうか?

  • mk278
  • お礼率61% (279/456)

質問者が選んだベストアンサー

  • ベストアンサー
noname#9431
noname#9431
回答No.3

おはようございます。 これはおそらく先の質問 http://oshiete1.goo.ne.jp/kotaeru.php3?q=1115230 の参考URLを参照されたのだと思いますが、 私もそのままではうまくいきませんでした。 そのURLの例は間違っているのだと思います。 (動かした後でコメントをいれて、動作確認をしなかったのかな?) ちなみにコメントを入れる場合は下のように、行末に; をつけてから入れるとよいようです。 基本的にエラーの原因は#2さんのご指摘のとおりです。 参考URLも良く見ると最後に"がありますよ。(それでも動かないと思いますが。。。) ただし、今の場合、最後に interact を入れないとうまく動かないとおもいます。(少なくとも私はそうでした。) この掲示板の過去の質問が参考になりました。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=924035 http://oshiete1.goo.ne.jp/kotaeru.php3?q=925167 #!/bin/sh HOST=192.168.1.105 UNAME=user01 PASSWD=xxxxxxxx TARGET=/cygdrive/c/cygwin/home/root/hoge /usr/bin/zip -r $TARGET.lzh $TARGET expect -c " set timeout 20 spawn scp -P 60001 $TARGET.lzh $UNAME@$HOST:/home/fat32/ ;こめんと expect \"password:\" ;こめんと send \"$PASSWD\r\" ;こめんと interact "

参考URL:
http://oshiete1.goo.ne.jp/kotaeru.php3?q=924035 http://oshiete1.goo.ne.jp/kotaeru.php3?q=925167
mk278
質問者

お礼

どうもお陰さまで解決しました。 有難うございました。

mk278
質問者

補足

皆様、ご回答有難うございます。お手数お掛けしております。 > http://oshiete1.goo.ne.jp/kotaeru.php3?q=1115230 > の参考URLを参照されたのだと思いますが、 はい、さようです。 > ただし、今の場合、最後に > interact > を入れないとうまく動かないとおもいます。(少なくとも私はそうでした。) > この掲示板の過去の質問が参考になりました。 > http://oshiete1.goo.ne.jp/kotaeru.php3?q=924035 > http://oshiete1.goo.ne.jp/kotaeru.php3?q=925167 有難うございます。参考になります。 > #!/bin/sh > HOST=192.168.1.105 > UNAME=user01 > PASSWD=xxxxxxxx > TARGET=/cygdrive/c/cygwin/home/root/hoge > /usr/bin/zip -r $TARGET.lzh $TARGET > expect -c " > set timeout 20 > spawn scp -P 60001 $TARGET.lzh $UNAME@$HOST:/home/fat32/ ;こめんと > expect \"password:\" ;こめんと > send \"$PASSWD\r\" ;こめんと > interact > " /home/fat32/ # expect コマンドの管理下でscpを実行する コマンドの管理下でscpを実行する: Not a directory invalid command name "こめんと" while executing "こめんと" となりました。序でに expect \"password:\" #こめんと send \"$PASSWD\r\" #こめんと interact " としてみましたら、 /home/fat32/ # expect コマンドの管理下でscpを実行する コマンドの管理下でscpを実行する: Not a directory usage: send [args] string while executing "send "xxxxxxxx\r" #こめんと" となってしまいました。 何か勘違いしてますでしょうか?

その他の回答 (3)

noname#9431
noname#9431
回答No.4

>expect \"password:\" #こめんと ごめんなさい。 expect \"password:\" ;こめんと の「こめんと」は#込みのつもりでした。 書きこんだあとに気づいたのですが、 やっぱり誤解がありましたね。 expect \"password:\" ;#こめんと としてください。 しかし、コメントなんてイランでしょうから、けずっていいとおもいますよ。

mk278
質問者

お礼

どうもお陰さまで解決しました。 有難うございました。

mk278
質問者

補足

お手数お掛けしましてスイマセン。 > expect \"password:\" ;#こめんと > としてください。 > しかし、コメントなんてイランでしょうから、けずっていいとおもいますよ。 expect -c " # expect コマンドを実行 set timeout 20 spawn scp -P 60001 $TARGET.lzh $UNAME@$HOST:/home/fat32/ ;# expect コマンドの管理下でscpを実行する expect \"password:\" ;#こめんと send \"$PASSWD\r\" ;#こめんと interact " として、上手くいきました。感動です。 \(^o^)/ これでリモートホストに自動バックアップできます。 どうも有り難うございました。m(_ _)m

  • s2t
  • ベストアンサー率79% (47/59)
回答No.2

おそらく、expect -c " のダブルクォーテーションが閉じられていないからではないでしょうか? こんな感じで試してみて下さい。 #!/bin/sh HOST=192.168.1.105 UNAME=user01 PASSWD=xxxxxxxx TARGET=/cygdrive/c/cygwin/home/root/hoge /usr/bin/zip -r $TARGET.lzh $TARGET expect -c " set timeout 20 spawn scp -P 60001 $TARGET.lzh $UNAME@$HOST:/home/fat32/ expect \"password:\" send \"$PASSWD\r\" " ↑これ

mk278
質問者

お礼

どうもお陰さまで解決しました。 有難うございました。

mk278
質問者

補足

> send \"$PASSWD\r\" > " > ↑これ 閉じ「"」が必要だったのですね。 /home/fat32/ # expect コマンドの管理下でscpを実行する コマンドの管理下でscpを実行する: Not a directory usage: send [args] string while executing "send "user01\r" # login: が出たらログイン名を打ち込む" となりました。ログイン名は不要でしたね。

回答No.1

こんばんは。 エラーメッセージによると、文が閉じられてない!って怒られてますよね。 「expect -c " # expect コマンドを実行」 この「"」ダブルコーテーションって必要なんでしょうか? 必要だとしてもひとつしかない(=カッコとして成り立ってない)し¥マークもついてないのが気になりました。 ※いま手元に環境がないんで私のほうでは試せません。  すいません。

mk278
質問者

お礼

どうもお陰さまで解決しました。 有難うございました。

mk278
質問者

補足

ありがとうございます。 「"」の直前に「\」を入れたら missing " while executing """ spawn: not found couldn't read file "login: ": no such file or directory send: not found couldn't read file "sword: ": no such file or directory send: not found となりました。 「"」を取っ払ったら expect: option requires an argument -- c usage: expect [-div] [-c cmds] [[-f] cmdfile] [args] spawn: not found couldn't read file "login: ": no such file or directory send: not found couldn't read file "sword: ": no such file or directory send: not found となりました。 「/usr/bin/expect -c "" # expect コマンドを実行」 としたら spawn: not found couldn't read file "login: ": no such file or directory send: not found couldn't read file "sword: ": no such file or directory send: not found となりました。でもspawnの行で引っかかってしまいます。 うーん、難しいんですね。

関連するQ&A

  • 自動scpスクリプトでキーが書き換わった場合にexpectでのif文の書き方は?

    度々スイマセン。 自動パスワード入力でscpコマンドを実行させたく思っています。 Win2kのCygwinで下記のスクリプトを試してみました。 $ cat ./test.sh #!/bin/bash -x HOST=foo.hoge.dyndns.net UNAME=user01 PASSWD=xxxxxxxx TARGET=/cygdrive/c/cygwin/home/root/hoge /usr/bin/zip -r $TARGET.lzh $TARGET expect -c " set timeout 20 spawn scp -P 60001 $TARGET.zip $UNAME@$HOST:$DSTNTN ; expect \"password:\" ; send \"$PASSWD\r\" ; interact " で、成功しましたがキーが変わった時には「yes」と自動で入力させたくて expect -c " set timeout 20 spawn scp -P 60001 $TARGET.zip $UNAME@$HOST:$DSTNTN ; if [ expect \"Are you sure you want to continue connecting (yes/no)?\" ] then ; send \"yes\r\" ;# yesと入力する。 fi; expect \"password:\" ; send \"$PASSWD\r\" ; interact " としてみたのですがキーが書き換わっていない場合(いきなりパスワードが聞かれる場合)、 user01@foo.hoge.dyndns.net's password: syntax error in expression "": premature end of expression while executing "if [ expect "Are you sure you want to continue connecting (yes/no)?" ] then " となってしまいます。一方、書き換わって、受け入れるかの問い合わせされた場合も同様の文法エラーとなってしまいました。 if文を入れる場合にはどう記述したらいいのでしょうか?

  • シェルスクリプトを使ったSCPのエラー

    お世話になります。 シェルスクリプトを使い、サーバAからサーバBへファイルを定期的にコピーしようと、以下のシェルスクリプトを作りました。 test.sh ================= #!bin/sh HOST1=hostB.com (さくらVPSサーバ) USER1=hugahuga PASS1=hogehoge TARGET_DIR1=/home/user/data/  #サーバB(転送先)のディレクトリ BACKUP_DIR1=/home/user/data_new/*  #サーバA(転送元)のディレクトリ expect -c " set timeout 30 spawn scp ${BACKUP_DIR1} ${USER1}@${HOST1}:${TARGET_DIR1} expect { \" Are you sure you want to continue connecting (yes/no)? \" { send \"yes\r\" expect \"password:\" send \"${PASS1}\r\" } \"password:\" { send \"${PASS1}\r\" } } interact " ================= sh test.sh すると、以下のようなエラーが出ます。。 /home/user/data_new/*: No such file or directory そのまんまだとは思うのですが、ファイルもディレクトリもありますし、上記スクリプトのSCPコマンド部分をコピペして、シェル上で実行すると普通にうまくいきます。 サーバAもBもUbuntu12.04です。 一体何が原因なのでしょうか・・

  • expectでscpのパスフレーズ入力を自動化

    別サーバーに存在するファイルを、scpでダウンロードしています。 これをcronを使用して自動実行させたいのですが、パスフレーズ入力の自動化で悩んでいます。 expectを使ってみましたが、以下のようにエラーもなく、反応でした。 expectの書き方が悪いのだと思いますが、ご教授いただけましたら助かります。 ○やりたいこと サーバーA(linux)から、サーバーB(linux, 192.168.1.100)のファイルをデイリーで自動ダウンロードしたい。 以下のtest.shを作って実行してみましたが、エラーも無く無反応です。 expectは導入されています。 ○環境 ・サーバーAからサーバーBへは、SSHでアクセスできる。 ・秘密鍵を/home/testuser/.ssh/に置いている。  ・サーバーBへは、パスフレーズを入力するだけでsshでログインできる。 ・パスワードでの認証はdisable ■手入力では、このようにファイルをダウンロードできています。 $ scp 192.168.1.100:/home/testuser/test.txt ./ Enter passphrase for key '/home/testuser/.ssh/id_dsa': ★ここでパスフレーズを手入力★ test.txt 100% 5 0.0KB/s 00:00 ■test.sh ----------- #!/bin/sh FILE=192.168.1.100:/home/testuser/test.txt TARGET=/home/testuser/ PASSWORD=hogehoge expect -c " set timeout 20 spawn scp $FILE $TARGET #expect \"Enter passphrase for key '/home/testuser/.ssh/id_dsa':\" ; #send \"$PASSWORD\r\"; " ■実行結果(エラー表示無し。ファイルはダウンロードされない) $ sh test.sh spawn scp 192.168.1.100:/home/testuser/test.txt /home/testuser/ $ 以上、よろしくお願いします。

  • scpをスクリプト内で実行してそれにpasswordを渡したい

    scpをスクリプト内で実行して,それにpasswordを渡すようなことをshellスクリプト又はPerlスクリプトで出来ますでしょうか? (私の調べたところ)scpはオプションでpasswordを渡すことがどうやら出来ないようなので, プロンプトが入力待ちになったときにそこにpasswordを流すようなことを実現したいのです. 因に, #!/bin/sh scp test.txt host.hogehoge.ne.jp:~ echo "passwd"; ではパスワード入力の所で止まって仕舞います. スクリプトに生にpasswordを記述するのはセキュリティ上マズイとはおもいますが,この問題はとりあえず別問題として下さい. よろしくお願いします.

  • expectでコマンド実行結果を変数に代入出来ない

    test.sh #!/bin/sh expect -c " set timeout -1 spawn telnet $1 expect "login:" ; send \"username\r\" expect "sword:" ; send \"password\r\" expect ${1} ; send \"start shell\r\" expect ${1} ; send \"set val=`date +%Y'-'%m%d`\r\" expect ${1} ; send \"echo $val\r\" expect ${1} ; send \"exit\r\" expect ${1} ; send \"exit\r\" exit " 例えばリモートホスト側で コマンド date +%Y'-'%m%d の実行結果を valに代入したいのですが 代入結果をechoコマンドで表示させても上記コマンド実行結果が 変数に代入されていないのか何も表示されません リモートホストに変数valを表示させるのがうまくいっていないんじゃないかと 思うのですが特殊文字($val)を正しく変数として解釈させる方法をご教示いただけませんでしょうか?

  • IP自動更新スクリプトがうまく動作しません

    環境 FreeBSD9 IP自動更新スクリプトを作成したのですが、うまく動作しません。メールでwget not foundが10分間隔で送られてきます。 wgetコマンドが見つからないと言ってるようです。/usr/local/bin/にwgetコマンドがあります。 また、コマンドラインでもwgetを使用してダウンロードできます。 vi /usr/local/bin/ddo.sh に以下のスクリプトを作成して、実行権限を与えました。 #!/bin/sh wget -O - "http://free.ddo.jp/dnsupdate.php?dn=hogehoge&pw=hogehoge1234" >> /var/log/result.log コマンドプロンプトでddo.shを実行すると、正常にIP更新がされログにその更新内容が記載されます。 スクリプトをcrontab -eに登録しました。 */10 * * * * /usr/local/bin/ddo.sh 10分間隔で実行はされるのですが、wget not found がメールに届き、ログに更新内容の記載がありません。 何がいけないのでしょうか? よろしくお願いします。

  • expectの構文について

    次のスクリプトを実行しました。 #!/bin/bash user="sarigennu" password="sarigennupassword" passwd="passwd" useradd $user; expect -c " spawn $passwd $user expect Enter\ send $password send \r expect Retype\ send $password send \r expect eof exit 0 " その結果として下のように標準出力されました。 どうしたら成功するでしょうか(一般ユーザのパスワードを変更できるようになるでしょうか?) spawn passwd sarigennu Changing password for user sarigennu. New password: BAD PASSWORD: it's WAY too short Retype new password: No password supplied No password supplied No password supplied passwd: Authentication token manipulation error

  • cronを介してのscpの挙動おかしい

    CentOS5系(64bit) expect5.45 Tcl8.6.0 Tk8.6.0 下記のデータダウンロードのスクリプトをcronに設定して自動実行していますが、 エラーも吐き出されずデータがダウンロードされません。 しかしながら、./download.shとコマンドを打鍵するとデータがダウンロードされます。 PCが壊れる前には、正常に動作していたスクリプトファイルなのです。 新しいPCに環境を再構築しまして、挙動がおかしいのですが、 インストール等がうまくいってないって事でしょうか。 お詳しい方、ご教授願えれば幸いです。 ー略- alive_time=3600 logFile=/home/admin/scp.log echo `date` >> $logFile expect -c " log_file $logFile set timeout $alive_time spawn scp $host $local sleep 1 expect { \"Are you sure you want to continue connecting (yes/no)?\" { send \"yes\r\" expect \"password:\" send \"${passwd}\r\" } \"password:\" { send \"${passwd}\r\" } } expect { \"denied\" { exit 2 } \ eof { sleep 1 exit 1 } } " ret=$? if [ $ret -eq 0 ] then echo "abort" >> $logFile else if [ $ret -eq 1 ] then echo "done" >> $logFile else if [ $ret -eq 2 ] then echo "fail" >> $logFile fi fi fi exit $ret

  • Linux メールアカウント自動生成

    現在、PHPでログイン機能のあるWEBサイトを開発しております。 そこでアカウントを作成したタイミングでバーチャルドメインのメールアドレス(info@www2.example.jp) を自動生成するプログラムを作りたいと思っております。 シェルスクリプトは初心者です。 OS: CentOS release 5.7 (Final) メールサーバ: qmail root権限有り 今のところ考えている方法↓ 1、メールアカウントを作るシェルスクリプトを作成 #!/bin/sh # domain domain=$1 # user name user=$2 # password passwd=$3 # mail address email=$2@$1 expect -c " set timeout 5 spawn /home/vpopmail/bin/vadddomain ${domain} expect \"Please enter password for postmaster:\" send \"${passwd}\n\" expect \"enter password again:\" send \"${passwd}\n\" interact " expect -c " spawn /home/vpopmail/bin/vadduser ${email} expect \"Please enter password for ${email}:\" send \"${passwd}\n\" expect \"enter password again:\" send \"${passwd}\n\" interact " 2、PHPのシステム関数でシェルスクリプトを実行 $result = exec("/home/example/create_email.sh www2.example.jp info passwd"); 【問 題】 ・root権限でないとシェルスクリプトを実行できない ・会員数が1千人規模になった場合の負荷 (会員は恐らく最大1千人くらいまでを見越しています。また、 全員にメールアドレスを作成しますが、必ずしも使用しない。) 問題の解決方法はありませんでしょうか?また、 もっといい方法はありませんでしょうか?。

  • シェルスクリプのexpect部分のコマンド実行方法

    シェルスクリプトのexpect -c以降の記述について相談させて下さい。 特定機器へのログインを行う場合に以下のパターンがあります。 パターン1 user=user PW=pass1 パターン2 user=user PW=pass2 ※プロンプトはuser@としています パターン1でログインできた場合はcommand Aを実行して終了 パターン2でログインできた場合はcommand Aを実行して終了 パターン1も2もログインできない場合即終了を期待して下記プログラムを作成しました。 expect -c " -略- expect \"Login:\" send \"user\n\" expect \"Password:\" send \"pass1\n\" sleep 1 expect { \"Login incorrect\" { send \"user\n\" expect \"Password\" send \"pass2\n\" expect { \"Login incorrect\" { exit 1 } \"user@\" { send \"command A\n\" expect \"user@\" send \"quit\n\" exit 1 } } } } \"user@\" { send \"command A\n\" expect \"user@\" send \"quit\n\" } } interact " しかし、上記のbraceでかこったsend部分がうまくコマンドとして実行されません。 別ファイルで#!/usr/bin/expectexpectの記述で記載すると動作する点は確認しています。 #!/usr/bin/bashにおいてexpect -cから記載するとbraceはそもそも使えないのでしょうか。 無知な質問かもわかりませんがお気づきの点があればご指摘いただけないでしょうか。 よろしくお願いします。