シンボリックリンクの一括張り直しシェル
先日5TBのHDDを買った流れでデータの整理整頓(ディレクトリ管理の見直しなど)をしていたところ、よく参照を行うファイルのシンボリックリンク集ディレクトリを作成していた箇所に大きな影響が出てしまい、一括でシンボリックリンクを張り直すことに。
…とインターネット検索でちょっと調べてみたら、一括で張り直すようなプログラムが見当たらない。そういうのって、ありそうなのに、なんで見つからないのか? 検索下手なのかな…と。
徐々に探すのが面倒くさくなってきたので、仕方がない「無きゃ作れスピリット」で、久々に頭の体操123!をする事に。
【2017/12/09 追記】
※↓エスケープ処理などをしておらず、メタキャラ系が入ると
動作が危険になる可能性があります。m(_ _)m
【ソース:replace-symbol.sh】
見て分かるように、シンボリックリンク内に第1引数の文字列がヒットしたら、それを第2引数の文字列に置換して、張り直す感じです。
…が、適当に作ったので、もしもコレをコピペする方は自己責任で。結構危険だと思います。(^^ゞ
実はコレ、昨晩(AM 3:00)に作成したのですが、この際17行目の引数$SRC, $DESTの順番を間違えてしまい(正確にはこの変数を作る箇所でawkに渡す$1, $2を間違えた)、「ln -fs」も相まって、約200個近くのファイルを破壊してしまいました。アギギー!!
普段定期的にバックアップを取っているので、リカバリは出来ましたが、サイズが数百GBオーダだったこと、rsyncで復元するにはかなり危険と判断したので、目視確認で手動のファイルコピーをしたという… お陰でこの復旧で昨日はほぼ徹夜で仕事に行きました…(´・ω・`)
最近のOSでは「# rm -rf /」は実行禁止になっているというのは聴きますが、「ln -sf」でもやっちまえるんだよなぁ~って感じです。
という感じで、普段寝てないから寝ぼけているという事ではなくて、普段手馴れていても勢い良くやってしまう…という目の覚めるような出来事でした。
現在はキレイにリンクを張り直せたので、事なきを得ましたが、「もしもミラーリングでバックアップしていたと思うとゾッとする… (ミラー先も破壊される)」、という事を思い知らされました。(もう何年も前にRAIDは止めて、手動で簡易コピー or rsyncするといったイケてないバックアップ運用にしています)
そして、このような簡単な自作シェルでもリンクが一気にピシッ!と揃った時は、物凄く気持ち良かったです。
最近のゲームプレーなんかよりも何倍も楽しかった気がしますw
さて、今日は昨日のお陰で疲労困憊なので、この糞日記を書いたら、AM 3:00までに寝るお。
…とインターネット検索でちょっと調べてみたら、一括で張り直すようなプログラムが見当たらない。そういうのって、ありそうなのに、なんで見つからないのか? 検索下手なのかな…と。
徐々に探すのが面倒くさくなってきたので、仕方がない「無きゃ作れスピリット」で、久々に頭の体操123!をする事に。
【2017/12/09 追記】
※↓エスケープ処理などをしておらず、メタキャラ系が入ると
動作が危険になる可能性があります。m(_ _)m
【ソース:replace-symbol.sh】
#!/bin/bash
if [ $# -ne 2 ]; then
echo "[Usage]"
echo " $0 <src string> <dest string>"
exit 1
fi
# ls の出力からシンボリックリンクの行だけ抽出
ls -l|grep '^l'|awk '{for(i=10;i<NF;i++){printf("%s%s",$i," ")}print $NF}'|while read line
do
# 元となるファイル名 -> 置換
SRC=`echo "${line}"|awk -v src=$1 -v dest=$2 -F' -> ' '{result = $2; gsub(src, dest, result); print result}'`
# 先となるファイル名 (元々のシンボリックリンクファイル)
DEST=`echo "${line}"|awk -F' -> ' '{print $1}'`
# シンボリックリンクを張り直す
exe=`echo "ln -sf '$SRC' '$DEST'"`
echo $exe
eval $exe
done
見て分かるように、シンボリックリンク内に第1引数の文字列がヒットしたら、それを第2引数の文字列に置換して、張り直す感じです。
…が、適当に作ったので、もしもコレをコピペする方は自己責任で。結構危険だと思います。(^^ゞ
実はコレ、昨晩(AM 3:00)に作成したのですが、この際17行目の引数$SRC, $DESTの順番を間違えてしまい(正確にはこの変数を作る箇所でawkに渡す$1, $2を間違えた)、「ln -fs」も相まって、約200個近くのファイルを破壊してしまいました。アギギー!!
普段定期的にバックアップを取っているので、リカバリは出来ましたが、サイズが数百GBオーダだったこと、rsyncで復元するにはかなり危険と判断したので、目視確認で手動のファイルコピーをしたという… お陰でこの復旧で昨日はほぼ徹夜で仕事に行きました…(´・ω・`)
最近のOSでは「# rm -rf /」は実行禁止になっているというのは聴きますが、「ln -sf」でもやっちまえるんだよなぁ~って感じです。
という感じで、普段寝てないから寝ぼけているという事ではなくて、普段手馴れていても勢い良くやってしまう…という目の覚めるような出来事でした。
現在はキレイにリンクを張り直せたので、事なきを得ましたが、「もしもミラーリングでバックアップしていたと思うとゾッとする… (ミラー先も破壊される)」、という事を思い知らされました。(もう何年も前にRAIDは止めて、手動で簡易コピー or rsyncするといったイケてないバックアップ運用にしています)
そして、このような簡単な自作シェルでもリンクが一気にピシッ!と揃った時は、物凄く気持ち良かったです。
最近のゲームプレーなんかよりも何倍も楽しかった気がしますw
さて、今日は昨日のお陰で疲労困憊なので、この糞日記を書いたら、AM 3:00までに寝るお。
find, xargsコマンドの文字列置換における、バッククォート内のプログラムの挙動
カレントディレクトリに
hoge1.txt
hoge2.txt
hoge3.txt
があったとして、
$ ls -1 *.txt 2> /dev/null|xargs -n 1 -I XXX echo `basename XXX .txt`
と実行して、「拡張子を抜こう」としたところ、
hoge1.txt
hoge2.txt
hoge3.txt
と表示されてしまった。
「???」となって、
$ find . -name "*.txt" -exec echo `basename {} .txt` \;
としても結果は同じ。
更に、
ls -1 *.txt 2> /dev/null|xargs -n 1 -I XXX basename XXX .txt
だと、
hoge1
hoge2
hoge3
と想定どおりの結果となった。
「なんでこうなるんだろ???」
詳細を調べた結果、バッククォート内でリプレースされる文字列と、プログラムに渡される引数に食い違いが発生する(argvの文字列と、文字列の長さが合ってない)みたいで、「これってシェルのバグじゃね?」みたいな感じに… (いや、私が無知なだけなのですが。(^^ゞ)
仕方がないので、別にプログラム(というかスクリプト)を組んで、そこで個別に変数に展開したものを渡して問題を解決しました。(策士策に溺れた。1行でエレガントに行きたかったのに…)
はぁぁ… これを調べてて1時間とか経つなんて、悲しいです。
今日もここまででタイムアウトかな。
「こんなハズではーなかったに。」(by アスレチックランドゲームのCM)
まぁ、今まで手作業だったものが、今後はコマンド一発なのでいいや。この時間は投資と思おう。
いつつぱつへんかん!(by ATOK)
ちなみに上の例はあくまで挙動の話で、私が実現したかった内容とは違います。m(_ _)m
hoge1.txt
hoge2.txt
hoge3.txt
があったとして、
$ ls -1 *.txt 2> /dev/null|xargs -n 1 -I XXX echo `basename XXX .txt`
と実行して、「拡張子を抜こう」としたところ、
hoge1.txt
hoge2.txt
hoge3.txt
と表示されてしまった。
「???」となって、
$ find . -name "*.txt" -exec echo `basename {} .txt` \;
としても結果は同じ。
更に、
ls -1 *.txt 2> /dev/null|xargs -n 1 -I XXX basename XXX .txt
だと、
hoge1
hoge2
hoge3
と想定どおりの結果となった。
「なんでこうなるんだろ???」
詳細を調べた結果、バッククォート内でリプレースされる文字列と、プログラムに渡される引数に食い違いが発生する(argvの文字列と、文字列の長さが合ってない)みたいで、「これってシェルのバグじゃね?」みたいな感じに… (いや、私が無知なだけなのですが。(^^ゞ)
仕方がないので、別にプログラム(というかスクリプト)を組んで、そこで個別に変数に展開したものを渡して問題を解決しました。(策士策に溺れた。1行でエレガントに行きたかったのに…)
はぁぁ… これを調べてて1時間とか経つなんて、悲しいです。
今日もここまででタイムアウトかな。
「こんなハズではーなかったに。」(by アスレチックランドゲームのCM)
まぁ、今まで手作業だったものが、今後はコマンド一発なのでいいや。この時間は投資と思おう。
いつつぱつへんかん!(by ATOK)
ちなみに上の例はあくまで挙動の話で、私が実現したかった内容とは違います。m(_ _)m
ファミレスで勉強、そして伝説へ…
ちょっとドラクエIIIっぽいタイトルでw
月曜日に仕事で面倒臭い作業が発生するので、「知識を駆使して楽にできないかなぁ~」と、金曜日の夜にファミレスで飯を食べながら、試行錯誤の勉強をしてました。

クラムチャウダーを食べながら、まずは何か描く。
月曜日に仕事で面倒臭い作業が発生するので、「知識を駆使して楽にできないかなぁ~」と、金曜日の夜にファミレスで飯を食べながら、試行錯誤の勉強をしてました。

クラムチャウダーを食べながら、まずは何か描く。
何時何分何十秒 地球が何回回った時?
小学生が言うアレじゃないですが、仕事でバッチ処理やったり、自宅で勉強がてら「とあるヘビーな計測」を行う時などに、「日オーダで処理していた際に、どれ位の時間がかかったか秒だけでなくて、何日何時間何分何秒で知りたい」とか思うことあり、その際に「dateコマンドとかのパラメータやコマンドの組み合わせで1行位で簡単に求められるんじゃないの?」なんて思っていたのですが、思いつきませんでした。(ヤレヤレ…自分の頭が固すぎて仕方ない…)
仕方がないので馬鹿正直に書きました…
仕方がないので馬鹿正直に書きました…