やりたいこと
リモートサーバからssh
(scp
でもいいんですが)で特定の条件を満たすファイルのみをローカルに持ってきたい(スクリプトで)。
調査した結果
単一のファイルやディレクトリをまとめてごっそり持ってくる方法はヒットしましたが、何か条件でフィルタした結果を持ってくる方法は特に見つかりませんでした。
結局どうするか?
A.リモートサーバで実行したいコマンドをヒアドキュメントに書いてそれをssh
に読み込ませました。
(クォーテーションを深く考えなくてよいのでこれが楽かと。)
コマンドバージョン
$ ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
$ tar --version
tar (GNU tar) 1.26
例
DATE=$(date '+%Y-%m-%d')
cat << EOF >cmd.txt
mkdir ${DATE}
grep -l keyword * | # or [awk '/keyword/{print FILENAME}' * | uniq]
[or awk '\$1==keyword{print FILENAME}' | uniq]
xargs -If cp -p f ${DATE}
tar -zcf - ${DATE}
rm -fr ${DATE}
EOF
cat cmd.txt |
ssh user@remoteServerAddress |
tar -zxf - -C localDirectory
説明 その1
リモート側で実行するコマンド
①
mkdir ${DATE}
圧縮用のディレクトリーを作成します。
このディレクトリーに、ローカルに持ってきたいファイルを詰め込みます。
この${DATE}
はローカルサーバ側で解釈するので、展開されてからリモートサーバへ渡されます。
というよりcmd.txt
の段階で既に展開されています。
②
grep -l keyword * | # or [awk '/keyword/{print FILENAME}' * | uniq]
[or awk '\$1==keyword{print FILENAME}' | uniq]
検索の仕方は何でもいいので、ファイル名だけ抽出します。
ファイル名がフルパスかどうかは、ローカルに持ってきたいファイルの置いてあるディレクトリ次第ですね。
awk
で使用している$1
はローカル側(シェルスクリプト)ではなくawk
に解釈して欲しいので\
を付けます。
③
xargs -If cp -p f ${DATE}
ファイルを作成したディレクトリへ放り込みます。
④
tar -zcf - ${DATE}
この辺が正直説明できるほど詳しくないのですが、ファイルを放り込んだディレクトリを圧縮します。
-
には本来圧縮後ファイル名を記載するのですが、すぐ解凍するからかパイプで渡すからなのか-
にしています。
⑤
rm -fr ${DATE}
お掃除です。不要であればしなくてもいいです。
説明 その2
ローカル側で実行するコマンド
cat cmd.txt |
ssh user@remoteServerAddress |
tar -zxf - -C localDirectory
リモート側で実行するコマンドをまとめてssh
に渡して実行させます。
その結果が圧縮ファイルになりますが、それをパイプで受け取ってtar
ですぐに解凍してしまいます。
-C localDirectory
は解凍場所の指定です。
補足
全てパイプでつなげることも可能です。
DATE=$(date '+%Y-%m-%d')
cat << EOF | ssh user@remoteServerAddress | tar -zxf - -C localDirectory
mkdir ${DATE}
grep -l keyword * | # or [awk '/keyword/{print FILENAME}' * | uniq]
[or awk '\$1==keyword{print FILENAME}' | uniq]
xargs -If cp -p f ${DATE}
tar -zcf - ${DATE}
rm -fr ${DATE}
EOF
参考にさせて頂いたサイト様
sshでリモートシェル実行時に``で括ったコマンドを使う - Qiita
ssh経由でのtarによるフォルダの圧縮・解凍方法 _ 俺的備忘録 〜なんかいろいろ〜
[Linux]ファイルの圧縮、解凍方法 - Qiita