[bash] rsync データバックアップのシェルでの変数参照方法

このQ&Aのポイント
  • rsyncを使用してローカルサーバのデータをリモートサーバにコピーするためのシェルスクリプトを作成しようとしています。
  • シェル内で変数を参照する際に、正しい書式を使用する必要があります。
  • 変数の参照方法を正しく記述することで、リモートサーバへのデータ移行が成功するはずです。
回答を見る
  • ベストアンサー

[bash] rsync データバックアップ

掲題の件で質問させて下さい。 rsync でローカルサーバ(A)のデータをリモートサーバ(B)にコピーしたいのですが、 そのためのシェルを作成でつまづいております。 ====================================================================== ▼シェルの中身 #!/bin/bash LOG=/var/log/backup.log PARAM=/etc/param/backup.param while read line; do echo `date +%Y/%m/%d" "%H:%M:%S`" "$line" のバックアップを取得します。" >> $LOG expect -c ' spawn rsync -auvz --delete -e "ssh -p 10022" '$line' root@BのIPアドレス:/backup/ expect "password:" send "パスワード\n" interact ' done < /etc/param/backup.param ====================================================================== ====================================================================== ▼実行結果 + LOG=/var/log/backup.log + PARAM=/etc/param/backup.param + read line ++ date '+%Y/%m/%d %H:%M:%S' + echo 2016/09/13 '15:05:25 /home/the-key のバックアップを取得します。' + expect -c ' spawn rsync -auvz --delete -e "ssh -p 10022" /home/the-key root@BのIPアドレス:/backup/ expect "password:" send "パスワード\n" interact ' spawn rsync -auvz --delete -e ssh -p 10022 /home/the-key root@BのIPアドレス:/backup/ root@BのIPアドレス's password: + read line ====================================================================== 実行結果を見ると、パラメータファイルの読み込み自体はうまく言っているのですが、 expect 内での変数の参照(とエスケープ文字)が正しくなく、ssh認証でおかしくなって しまっているようです。 変数の表記をどのように記述すればBへのデータ移行が出来るようになるのでしょうか。

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

  • ベストアンサー
  • freetaka
  • ベストアンサー率53% (106/197)
回答No.1

前回もエスケープ処理で苦しんでいたようですが できればエスケープ処理をあまりしないような スクリプトを組むようにすると間違いが少なくなります それと処理の中でシングルクォーテーションを使用したため expect -c ' spawn rsync -auvz --delete -e "ssh -p 10022" ' までで expect の処理が終わってしまっています '$line' のようにしてしまうと シングルクォーテーションの中で変数の内容が展開されず そのまま $line と表示されます そしてechoの中のバッククォーテーション中も同様です どうしてもエスケープ処理したいのであれば エスケープ処理の仕方をネットで調べればいろいろでてきます dateコマンドのところで使っているバッククォーテーションの場合は 終わりのバッククォーテーションのところまでをコマンドとみなすので ダブルクォーテーションがそのまま中で使えるのも覚えておくとよいでしょう 次の1行を修正 echo `date +%Y/%m/%d" "%H:%M:%S`" "$line" のバックアップを取得します。" >> $LOG ↓ echo "`date "+%Y/%m/%d %H:%M:%S"` ${line} のバックアップを取得します。" >> $LOG LOGの中をまっさらにしてから中に記述したいのであれば echoの前に次を追記しこんな感じに : > $LOG echo "`date "+%Y/%m/%d %H:%M:%S"` ${line} のバックアップを取得します。" >> $LOG 内容も表示しつつ追記でログ保存したいなら echo "`date "+%Y/%m/%d %H:%M:%S"` ${line} のバックアップを取得します。" | tee -a $LOG 次の1行を修正 spawn rsync -auvz --delete -e "ssh -p 10022" '$line' root@BのIPアドレス:/backup/ ↓ spawn rsync -auvz --delete -e "ssh -p 10022" $line root@BのIPアドレス:/backup/ 次の1行を修正 done < /etc/param/backup.param ↓ done < $PARAM まとめると #!/bin/bash LOG=/var/log/backup.log PARAM=/etc/param/backup.param while read line; do echo "`date "+%Y/%m/%d %H:%M:%S"` ${line} のバックアップを取得します。" >> $LOG expect -c ' spawn rsync -auvz --delete -e "ssh -p 10022" $line root@BのIPアドレス:/backup/ expect "password:" send "パスワード\n" interact ' done < $PARAM テストしてませんがうまく動作するとよいですね エラー等がでる場合は補足ください 以上参考までに

The-Key
質問者

お礼

2日連続のコメント、本当にありがとうございます。 頂いた内容に修正してみたところ、実行結果で spawn rsync -auvz --delete -e ssh -p 10022 $line root@BのIPアドレス:/backup/ となり、変数line を読み込んでくれない状態となってしまいました。 その後、回答 No,2 の trapzium さんのアドバイスに従い、認証鍵による ssh 接続にしたところ、うまくバックアップを取得することが出来ました。 一安心したところで freetaka さんへのお礼コメント用にパスワード認証バージョンの方を実行したところ、なぜか正常終了しました、、、 スペースやタブなどの空白部分に何か問題があったのか、今となっては真実は闇の中ですが、結果として2通りのやり方を知ることが出来ました。 失敗時の処理結果を記載できなくて申し訳ないですが、これにて解決とさせて頂きます。 ベストアンサーは、2日連続でコメント頂いた freetaka さんを選ばせて頂きます。 ありがとうございました!

その他の回答 (1)

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.2

何か苦労してるようなので、前提条件に突っ込むのもあれなので黙っていましたが、ssh 使うならパスワード入力を不要にした方が簡単だと思います。 いくつか方法はありますが、汎用的なのは空のパスフレーズで公開鍵作成して、 ssh-keygen -t ed25519 -N "" -C "for rsync" -f ~/.ssh/id_backup ssh BのIPアドレス -p 10022 -l root "cat >> ~/.ssh/authorized_keys" < ~/.ssh/id_backup.pub しておけば expect 使わずに rsync -auvz --delete -e "ssh -p 10022 -i $HOME/.ssh/id_backup" "$line" root@BのIPアドレス:/backup/ できます。 そんな方法もあるよということで。あと古い ssh だと ed25519 使えないので ecdsa か dsa

The-Key
質問者

お礼

コメントありがとうございます。 こちらの方法で無事バックアップをすることが出来ました! 最初の作成時に「公開鍵作るよりパスワード認証の方が作り込みラクじゃない?」と思い、見事にハマってしまいました。 結果としてどちらの認証方式でも処理が出来るようになったので感謝です。 ありがとうございました!

関連するQ&A

  • [bash] rsync データバックアップ

    掲題の件で質問させて下さい。 rsync でローカルサーバ(A)のデータをリモートサーバ(B)にコピーしたいのですが、 そのためのシェルを作成でつまづいております。 ▼シェルの中身 ---------------------------------------------------------------------- expect -c " spawn rsync -auvze \"ssh -p 10022\" /tmp/ root@BのIPアドレス:/backup/ expect \"root@BのIPアドレス's password:\" send \"パスワード\" exit 0 " ---------------------------------------------------------------------- ▼実行結果(sh -x /シェルのパス) ---------------------------------------------------------------------- + expect -c ' spawn rsync -auvze "ssh -p 10022" /tmp/ root@BのIPアドレス:/backup/ expect "root@BのIPアドレス'\''s password:" send "パスワード" exit 0 ' spawn rsync -auvze ssh -p 10022 /tmp/ root@192.168.23.44:/backup/ root@192.168.23.44's password:[root@TEST01 scripts]# ---------------------------------------------------------------------- 実行結果を見ると、シングルクォーテーションのエスケープが出来ていない?ようです。 実行結果2行目「expect "root@BのIPアドレス'\''s password:"」 何通りか書き方を変えては見たのですが、どれもうまくいかず、、、 どのように書けば ssh ログインをしてサーバBにデータを送れるようになりますでしょうか。 ※パスワード認証はダメだよ!や、パスワード直書きはダメだよ!といったご指摘は  控えて頂けると助かります。とり急ぎ目の前の問題をクリアしたいので。

  • expectで複数台にログインしscpする。

    シェルの超初心者です。よろしくお願いします。 下記のようなシェルを作りたいのですがうまくいきません。 3台のパソコンA, B, Cがあるとします。 まず、AからBにssh接続し、シスログをAにscpします。 その後、AからCにssh接続し、シスログをAにscpします。 下記が、作成したものです。 どうぞ、アドバイスよろしくお願いいたします。 #!/usr/bin/expect set timeout 5 spawn ssh B@xxx.xxx.xxx.xxx expect "Enter passphrase for key" send "Password\n" spawn scp /var/log/messages A@xxx.xxx.xxx.xxx:/tmp/log01.log expect "password" send "Password\n" send "exit\n" spawn ssh C@xxx.xxx.xxx.xxx expect "Enter passphrase for key" send "Password\n" spawn scp /var/log/messages A@xxx.xxx.xxx.xxx:/tmp/log02.log expect "password" send "Password\n" send "exit\n" interact

  • CentOS Stream鍵ファイルでrsync

    CentOS Stream release 8 鍵ファイルでrsync CentOS Stream release 8の2台のマシンでAからBにフォルダをコピーするシェルを書きたいです。 com-a:192.168.1.11 com-b:192.168.1.12 com-bのログインは鍵ファイルを作っています。 com-aからcom-bにsshでログインするところまではできています。 <192.168.1.11から> ■通常のログイン ssh -i 鍵ファイル root@192.168.1.11 ここまでできていrます。 パスワードは求められません。 ■rsyncでフォルダーのコピー rsync -auvz --delete -e ssh /dir-from root@192.168.1.12:/dir-to/ しかし、これではパスワードを求められます。 rsyncで鍵ファイルは指定できないですか?

  • cron で rsync が実行できない

    サーバ2台を使い rsync にて 同期をとっているのですが、 cron を使って自動化しようとしたところ ツマづいてしまいました。 rsync -au -e ssh {from} {to} 手動にて上記実行するとコピー実行できるのですが * * * * * rsync -au -e ssh {from} {to} >> err と crontab を設定したところ コピーが出来ていません。 /var/log/cron をみると1分置きに (root) CMD (rsync -au -e ssh {from} {to} >>err) とあり実行はされているようです err を確認しましたが特にエラー記述もありませんでした。 どういった箇所を調べればよいか助言いただけると助かります。 よろしくお願いします。

  • シェルのwhile文を使ってexpect処理

    環境:CentsOS 5 expectを使ってリスト行文、処理を行わせたい。 while文を使用してシェル内に記述しているexpect構文を リスト文処理をしたいのですがどうもうまく実行できません。 以下のようにsuを行い、Passwordプロンプトが返ってきたときに interactで標準入力モードに戻し、手入力後、引き続き、while文で 後続の処理(echo test;)を実行し、また、expect構文にループするというものです。 以下の構文を実行すると、Passwordプロンプトが返ってきた後 通常プロンプトが返ってきて終了になってしまいます。 因みに、以下の処理ならexpectは必要ないのでは?とおもわれるとおもうのですが 実際にやりたいことは、su処理ではなく他の処理で特定の個所のみプロンプトが返ってきた場合に 手入力したいといったことがあるためです。 どなたかわかる方教えて頂けますと助かります。 ■test.sh #!/bin/sh LISTFILE=/tmp/test.list; while read LINE; do expect -c " set timeout -1 spawn su - root expect \"Password\" interact " echo "test"; done < $LISTFILE

  • レンタルサーバ同士のバックアップ

    レンタルサーバ同士で毎日バックアップを取りたいと考えています。このサイトでいろいろと検索した所、rsync + sshで行うようですが、レンタルサーバ同士でも設定は可能なのでしょうか? 両方ともcrontabは使用可能です。 Aサーバの/home/hoge/backup/内をそのままミラーの形で、 Bサーバの/home/hoge/backup/にバックアップしたい。 ※Aサーバの/home/hoge/backup/には現状10個程あるDBのmysqldumpを毎日取り、1ヶ月後に削除する設定にしています。 ※Bサーバでの運用は考えていません。 Aサーバ:hoge1.com Linux 2.6.9-42.ELsmp Bサーバ:hoge2.com Linux 2.4.34.1-p3-nonsmp-JWH Aサーバのcrontabに見よう見まねで下記をセットした所、 rsync -avz -e ssh --delete /home/hoge/backup/ hoge2.com:/home/hoge/backup/ rsync error: syntax or usage error (code 1) at main.c(891) とエラーになりました。 それとも、rsync + sshは諦めて、ftpコマンドで送った方がよろしいのでしょうか?

  • cronで週ごとのバックアップをとりたい。

    下記のようなスクリプトを毎週月曜日に実行しています。 月曜日の日付を7で割った商の値*によりback-*に保存する仕組みです。 しかし、月によりback-0やback-4に保存されない場合があり、 もっと、スマートなやり方があるのかなと思います。 もし、ご存じでしたらお教えください。 (4週分ぐらいバックアップできれば問題ありません。) #!/bin/sh a=`date +%d` b=`expr $a / 7` case $b in 0) rsync -acouv --stats --delete /home /backup/back-0 ;; 1) rsync -acouv --stats --delete /home /backup/back-1 ;; 2) rsync -acouv --stats --delete /home /backup/back-2 ;; 3) rsync -acouv --stats --delete /home /backup/back-3 ;; 4) rsync -acouv --stats --delete /home /backup/back-4 ;; esac

  • rsyncのPermission denied

    CentOS6.3にて rsync -avvz root@172.30.1.21:/mnt/iptables/ /mnt/nas/iptables/ を実行しました。ログとして以下のものが出力されました。 <ログ> opening connection using: ssh -l root 172.30.1.21 rsync --server --sender -vvlogDtprze.iLs . /mnt/iptables/ root@172.30.1.21's password: receiving incremental file list delta-transmission enabled (1)rsync: chgrp "/mnt/nas/iptables/." failed: Permission denied (13) <質問1> (1)の意味がわからないのですが、rsyncは何をしようとしてなぜパーミッションエラーが出ているのでしょうか?  ・root@172.30.1.21:/mnt/iptables/ は、別サーバのNFSをマウントしています。  ・/mnt/nas/iptables/ は、NASドライブをcifstestユーザでマウントしています。  【コマンド:mount -t cifs //NASのIP/cifs/ /mnt/nas/iptables/ -o username=cifsuser,iocharset=utf8,codepage=932】  (NASにrootユーザが作れなかったため)  ・rsync実行時は、rootユーザー。 になります。 <質問2> ただ、パーミッションエラーが出てたのですが、以下ログが出力されており、 データのコピーが完了していました。 total: matches=0 hash_hits=0 false_alarms=0 data=3999447313 sent 546 bytes received 493957830 bytes 1123909.84 bytes/sec total size is 3999426304 speedup is 8.10 rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1505) [generator=3.0.6] ためしにコピーされた一つのコピー元ファイル と コピー後のデータをdiffしてみた所 エラーも出ませんでした。サイズも一緒。 これは正しくコピーできていると信じていいのでしょうか? ご教授おねがいします。

  • rsyncの挙動について

    お世話になります。 現在AサーバからBサーバに対して、定期的にrsyncにてサーバ内ファイルの同期を行っています。 毎日更新されているファイル数が数十万ということと、回線が細い為に同期完了まで約2時間程かかります。 その際少し気になる点があります。 例えば、数十万ある同期対象ファイルの中でhoge.txtというファイルがあったとします。このファイルは動的に書き込みが行われるログファイルです。中身はWEBのアクセスログのようなものです。 このファイルを含む数十万のファイルをrsyncで同期を行った場合以下のような現象が起こります。 --条件------------------------------------------- rsync開始時刻 :01:00 rsync完了時刻 :03:00 rsync開始時の同期元Aサーバにあるhoge.txtのタイムスタンプ :00:58 rsync完了時の同期先Bサーバにあるhoge.txtのタイムスタンプ :00:58 rsyncオプション :rsync -auvvz -e /usr/bin/ssh --exclude '*~' --delete ------------------------------------------------- 上記条件及び結果の元、Bサーバに同期されたhoge.txtを見てみるとファイルのタイムスタンプ自体はAサーバでrsyncを開始した時点でのタイムスタンプ(00:58)なのですが、ファイルの中身を見てみると、ログファイル内にて01:30にアクセスがあったという記録が追記されています。 恐らくは約2時間かかるrsync実行中のうち、01:30以降にAサーバからBサーバに同期が行われたと思うのですが、それであれば、hoge.txtのタイムスタンプ自体も01:30に変わっていなければならないはずだと思うのです。 ちなみにこのhoge.txtというログファイルは書き込みが行われる毎にファイルのタイムスタンプも更新されます。 そこで質問させて頂きたいのですが、rsyncの挙動としてこのようなことはありえるのでしょうか? それではどうぞよろしくお願い致します。

  • rsync -vr /home/data /mnt/win >> backup.logのリダイレクトの日本語表示について

    centos5 にて Samba version 3.0.28-1.el5_2.1 を運用中です、 Sambaのデータを他のwindowsパソコンのフォルダ(//192.168.0.5/backup)にバックアップするために以下のようなシェルスクリプトを書きcronで実行しています。 #!/bin/bash echo 'バックアップ日' > backup.log date >> backup.log mount -t cifs -o username=root,password=abcd //192.168.0.5/backup /mnt/win echo 'マウント完了' >> backup.log rsync -vr /home/data /mnt/win >> backup.log cronにて自動実行された後backup.logを覗いてみると バックアップ日やマウント完了という文字はきちんと日本語になってリダイレクト されているのですが、 rsync -vr /home/data /mnt/win >> backup.log の結果のログがアルファベットはいいのですが、日本語のフォルダ名やファイル名が#944\#948\#492\#483\#309といった感じ何かのコードみたいになって 何がバックアップされたか分かりません。 きちんと日本語の表記になる方法があればお教え願います。