2012-02-10 13 views
2

私はssh経由でファイルをコピーし、転送中にハッシュファイルを作成するバックアップスクリプトを用意しています。さらにpvは、プログレスバーを表示するために使用されます。Bash配管:1行目以降の入力を分割し、1行目と別のコマンドを実行する

ssh $host "cat '$src_dir/$filename'" \ 
    | pv --bytes --eta --progress --rate --timer --wait $opts \ 
    | tee "$filename" \ 
    | sha1sum > "$filename.sha1" 

正しく、私はpvにファイルのサイズを渡す必要がプログレスバーを表示します。現時点では、最後のバックアップファイルのサイズを指定することでこれを行います。

1回のバックアップで複数回認証する必要がないため、すべてが1 sshコールで完了することが重要です。 SSHキーは使用中ですが、パスフレーズで保護されています。

私の考えはssh $host "stat -c%s '$src_dir/$filename'; cat '$src_dir/$filename'"を呼び出し、1行目の後に出力を分割することです。私はファイルサイズを読み込み、入力の残りの部分にpvを呼ぶことができました。

バックアップスクリプトが正常に動作しています。これは、それを楽しむための単なる練習です。どのようなアイデアをいただければ幸いですが、スクリプト全体を完全に書き直すつもりはありません。特に私はscpに切り替えることはありません。なぜなら私は転送中にハッシングを行うことができず、そのためにローカルストレージを信頼したくないからです(もちろん、私はしますが、なぜハッシュを行うのですか?)。

アップデート:私はこれをやってしまった:

ssh $host "cd '$src_dir' && stat -c%s '$filename' && sha1sum '$filename' && cat '$filename'" | { 
     read size; 
     head -n 1 > "$filename.sha1"; 
     pv --bytes --eta --progress --rate --size $size --timer --wait > "$filename" 
    } 

それは完璧に動作し、ハッシュがリモートサイトで計算されるという利点を有しています。ディスクに書き込む前ではなく、ネットワーク転送を行う前に。この例では

+1

これを行う唯一の理由は、sshキーパスフレーズを複数回入力したくない場合は、代わりにssh-agentを使用する必要があります。 ssh-agentを使用すると、鍵を一度ロック解除し、ssh-agentに(安全に)それらを追跡させます。完了したら、次の実行時にエージェントを再び使用したり、キーを忘れるように指示したりすることができます。 –

+0

@MikaelAuno:お返事ありがとうございます。私はssh-agentについて知っています。私がssh-agentの設定を壊さなかったなら、私はそれを使用します。しかし、何らかの理由でssh-agentを使用しない同僚とスクリプトを共有したいのです。 –

答えて

2

は、私はサイズのためのフォーマット文字列のZを使用してOSX、上のSTATを使用します。

 
$ { stat -f %z input; cat input; } | { read s; echo $s; } 

は、あなたのsshの呼び出しで最初のコマンドリストを交換し、そしてあなたのPVリストでエコーを置き換えますあなたは行くのが良いです。言い換えれば、あなたの最後のコマンドは次のようになります。

 
$ ssh $host "stat -c%s '$src_dir/$filename'; cat '$src_dir/$filename'" | { 
    read size; 
    pv --bytes --eta --progress --rate --timer --wait --size $size | 
    tee "$filename" | 
    sha1sum; } > "$filename.sha1" 

I注意すべきいくつかのこと:私は、PVへのアクセスを持っていないと上記をチェックしませんでした。 私は と思うので、あなたの行の続きをパイプ記号に置き換えました。

もう一つのアイデア:パイプの右側に、あなたができる:

 
{ pv --bytes ... --size $(sed 1q) | 
... 

これは間違いなく、sedの最初の改行を過ぎて読んでいないに依存している、そしてそれはいずれかによって保証されている場合、私は知りません標準ではありますが、それは...ああ、私のsedは--version、-?、-hをサポートしていません。OS Xのパッケージ管理システムもよく分かりません。ランニング。これは、BSD sedのいくつかのバージョンで動作します...

+0

それは素晴らしい作品です!私はそれが普通のbash構文と特別なプログラムなしで動作することにかなり驚いています。それぞれのコマンドの後に '{}'のカッコとセミコロンの中にスペースを入れることが絶対必要であることに注意してください。大変ありがとうございました! –

+0

@haloでは、* closing *ブレースの前にセミコロン(または改行または '&')が必要です。 –

+0

@glennjackman注釈をありがとう。実際には、最後のコマンドと閉じる '}'ブレースの間に改行を使用することもできます。私が言及した他のセミコロンについて:あなたはコマンドを分割するために何かが必要です;-)改行はウィリアムが示したようにも行います。 –

関連する問題