検索

findコマンドの検索結果で得られたファイルを特定ディレクトリに同期させるときに苦労した点のメモ

narou.rbっていうなろうやらカクヨムからのweb小説をepubやらmobiやら電子書籍リーダに使いやすい形式に変換してくれる、超便利なプログラムがある。narou.rbにはいままでダウンロードしてたファイルを管理する機能もあって、アップデートのサブコマンドを入力すると、Web版が更新された状態を反映できる優れもの。

んでその処理と同時にプログラムが普段作業ディレクトリにしてる場所から普段電子書籍設置してるディレクトリにコピーする処理を書いたものをcronに打ち込んで毎日実行させたかった。

最初に作ったスクリプト

ちなみにnarou.rbはdocker版を使用している。-vオプションでnarou.rbが作業兼データを保存するのに使ってるディレクトリをホストOS側のディレクトリにマウントさせてコンテナが消し飛んでも大丈夫なように利用している。

#!/bin/bash
docker run --rm -v /home/name/Documents/narou.rb/:/novel -it whiteleaf/narou narou u
OLDIFS=$IFS
IFS=`
`
for i in $(find /home/name/Documents/narou.rb/小説データ/ -name *.epub)
do
        cp -a "$i" /home/name/Documents/電子書籍/小説/Web小説_epub
done
IFS=$OLDIFS
Code language: JavaScript (javascript)

IFSに改行で区切る様に設定したあとに、findの結果を一行ずつ、iにぶち込んでforで回す。これでうまくいくと思うじゃん?

cp: '/home/name/Documents/narou.rb/小説データ/カクヨム/1177354054881165840 この勇者が俺TUEEEくせに慎重すぎ る/[土日 月] この勇者が俺TUEEEくせに慎重すぎる.epub'$'\n''/home/name/Documents/narou.rb/小説データ/小説家 になろう/n4830bu 本好きの下剋上 ~司書になるためには手段を選んでいられません~/[香月 美夜] 本好きの下剋上 ~司書になるためには手段を選んでいられません~.epub'$'\n''/home/name/Documents/narou.rb/小説データ/小説家になろう/n8611bv ありふれた職業で世界最強/[厨二好き/白米良] ありふれた職業で世界最強.epub' を stat できません: そのようなファイルやディレクトリはありません
./Dc-narou.rb-upd: 行 12: 対応する ``' を探索中に予期しないファイル終了 (EOF) です
./Dc-narou.rb-upd: 行 13: 構文エラー: 予期しないファイル終了 (EOF) です
Code language: plaintext (plaintext)

なぜか全てのループの$iの内容がくっついて更に$’\n’とかいう謎の文字列が間に挟まってエラー吐くんだよね。
因みにcpじゃなくてecho使ってiを出力させるとちゃんと一行ずつとれるんだよ。まじで意味不明。

xargsというコマンドの存在を思い出した

昔学校でLinuxの授業やってるときに、パイプでxargsに値を渡すと次のコマンドの引数として利用できることを思い出した。んで以下のようなソースになった。

 #!/bin/bash
  2 docker run --rm -v /home/name/Documents/narou.rb/:/novel -it whiteleaf/narou narou u
  3 OLDIFS=$IFS
  4 IFS=`
  5 `
  6
  7 find /home/name/Documents/narou.rb/小説データ/ -name *.epub |xargs -i rsync {} /home/name/Documents/電子書>    籍/小説/Web小説_epub
  8
  9 IFS=$OLDIFS
Code language: Bash (bash)

rsyncが使えそうだったのでcpをやめた。普通に動いてくれた。cpと違って初期がアップデートされても差分だけコピーするし、cronで回しててもサイズとタイムスタンプに変更がなければ動かないので無駄がない。とりあえず、findのファイルを特定ディレクトリに同期させる問題は解決。

そもそもnarou.rbに変換後に特定のディレクトリにファイル移す機能がある…

上のスクリプト作る作業で2日程度悩みまくって完成した数分後に思いついた。でもdockerって一つのコンテナに対して複数のディレクトリってマウントできんの?っと思ったが…

sudo docker run --rm -v /home/name/Documents/narou.rb/:/novel -v /home/name/Documents/電子書籍/小説/Web小説_epub/:/mnt -it whiteleaf/narou narou d https://ncode.syosetu.com/n6789do/
Code language: JavaScript (javascript)

試しに一つ小説ダウンロードしたらできてしまった…。つまりこれnarou updateも問題ねぇじゃん。

#!/bin/bash
docker run --rm -v /home/shoji/Documents/narou.rb/:/novel -v /home/shoji/Documents/電子書籍/小説/Web小説_epub/:/mnt -it whiteleaf/narou narou u
Code language: JavaScript (javascript)

これだけシェルスクリプトに書いてcronにおいときゃ毎日更新チェックして所定のディレクトリにepubファイルを設置できるってことだ。

なんか色々徒労に終わってしまった気分だがxargsの使い方をある程度記憶できたし、dockerの熟練度も上がったから良しとしよう。