ほとんどお遊びな感じネタですが、
ちょっとだけfind+readlink使うことがあったのでそれも兼ねてのメモです。
最終目的はこんな感じ
ってことで、こんな感じの順番で最終目的に到達したいと思います
1.シンボリックリンクの一覧を表示
2.とある'1つの'シンボリックリンクのリンク元を表示
3.1と2を使ってとあるディレクトリ内の各シンボリックリンクの絶対パスを一覧で表示
0.前提
1〜3の前にこんな感じのディレクトリだったとします的な構造を示します
# pwd /home/hoge/test_readlink # tree . |-- a01 | `-- a02 | `-- a03 | `-- a.txt |-- b01 | `-- b02 | `-- b.txt `-- c01 |-- a_link.txt -> ../a01/a02/a03/a.txt `-- b_link.txt -> ../b01/b02/b.txt
1.シンボリックリンクの一覧を表示
こちらは簡単でfindコマンドと-type -lオプションを使います
# pwd /home/hoge/test_readlink # find ./ -type l ./c01/b_link.txt ./c01/a_link.txt
2.とある'1つの'シンボリックリンクのリンク元を表示
※ 念のため # pwd /home/hoge/test_readlink ※ 一覧したファイルがシンボリックリンク # ls c01 a_link.txt b_link.txt ※ リンク元を相対パスで表示 ※ 表示されているのはカレントディレクトリからのパスではなくリンクから見たリンク元です # readlink c01/a_link.txt ../a01/a02/a03/a.txt ※ リンク元を絶対パスで表示 # readlink -f c01/a_link.txt /home/hoge/test_readlink/a01/a02/a03/a.txt
3.1と2を使ってとあるディレクトリ内の各シンボリックリンクの絶対パスを一覧で表示
これが意外にすんなりできませんでした(--;
2で'1つの'と強調しましたが、要するに一覧をいっきにreadlinkさせるやり方がすんなり出てこなかった。。
ってことで、失敗のほうも載せておきます
xargs使う(失敗例)
一覧はfindで簡単に出せたのでそれを次のコマンドへ渡せば良いか、
という単純な考えのコマンド。
# find ./ -type l | xargs /bin/readlink -f /bin/readlink: extra operand `./c01/a_link.txt' 詳しくは `/bin/readlink --help' を実行して下さい.
xargsについてはこちらなんかに詳しく書いてあります。
今回の例で言うとxargsに「期待した結果」と「実際の結果」はこんな感じになってしまいます
※ 期待した結果
/bin/readlink -f ./c01/b_link.txt
/bin/readlink -f ./c01/a_link.txt※ 実際の結果
/bin/readlink -f ./c01/b_link.txt ./c01/a_link.txt
xargs使う(成功例)
xargsの-nオプションを使うことで簡単にできました
(実際はxargsじゃダメなのかと思って結構他を探しちゃいました。。。)
# find ./ -type l | xargs -n1 /bin/readlink -f /home/hoge/test_readlink/b01/b02/b.txt /home/hoge/test_readlink/a01/a02/a03/a.txt
-n[number]で「number を最大限度に標準入力からできるだけ多くの引数を読み込んでコマンド文字列を実行する」らしいです。
オプションについてはこちらなんかを参考にさせて頂きました
find+for文でやる
↑の正解にたどりつく前にxargs以外の方法で探してしまって
変数に入れてループすりゃいいやって方法も思いついたのでそっちも載せておきます
何かの役に立ちますように(-人-)
# for slinks in $(find ./ -type l); do echo $slinks"|"`/bin/readlink $slinks`"|"`/bin/readlink -f $slinks` ; done ./c01/b_link.txt|../b01/b02/b.txt|/home/hoge/test_readlink/b01/b02/b.txt ./c01/a_link.txt|../a01/a02/a03/a.txt|/home/hoge/test_readlink/a01/a02/a03/a.txt
findの結果を$()で囲んで変数としてfor文で回します。
また、せっかくなので
という感じで表示してみました。
理解してたつもりでも理解してないこと多いなーと思う今日このごろです。