再び追記_2012/10/31_15時頃
もう少しコマンドの数を減らせることに気づいたので追記します
調べたいファイル名=~/.vim if [ -n "`find \"${調べたいファイル名}\" -maxdepth 0 -type l`" ];then echo "シンボリックリンクです" else echo "シンボリックリンク以外の何か(存在しない場合も含む)" fi
ちなみに速度は比較していないのでどれが早いのか不明
シンボリックリンクであれば標準出力されるのでそれを利用して-nオプションでされたかどうかを判定してます
ちなみにfindのtypeのlを変えることによってディレクトリやソケットや名前付きパイプにも応用できたりします
ちなみにちゃんと``を""で囲ってやらないと正常に動かないので注意…一度囲まないで公開してしまった
そしてmaxdepthも指定しないとディレクトリを指定した場合に期待していない結果になるけどosによってはこのオプションはないらしいから試してないけどhead -1にパイプしてもいいかもしれない
改良後(追記後)
何度もlsを実行しなくてもいいことに気づいたので追記します*1
調べたいファイル名=~/.vim ls -l1ad ${調べたいファイル名} 2>/dev/null|grep "^l" > /dev/null 2>&1 if [ ${?} == "0" ];then echo "シンボリックリンクです" else echo "シンボリックリンク以外の何か(存在しない場合も含む)" fi
最初にlというシンボリックリンクを示す文字があるかで判定しています
存在しないファイルを見に行った時もlから始まる文字が出力されるのですが
それはエラーなので2>/dev/nullで捨てて無視できるようにしてます
以下は改良前の記事(追記前)
if [[ -L ~/.vim ]] then #シンボリックリンクだったら else #そうじゃなかったら fi
のように書けるみたいですが
もしかしたらshスクリプトではできない?みたいですし
書いてみました
追記:ファイル名の最後が@でもちゃんと動くように修正しました
調べたいファイル名=~/.vim ls -F1ad ${調べたいファイル名} 2>/dev/null|grep "@$" > /dev/null 2>&1 if [ ${?} == "0" -a "$(ls -F1ad ${調べたいファイル名} 2>/dev/null)" != "$(ls -1ad ${調べたいファイル名} 2>/dev/null)" ];then echo "シンボリックリンクです" else echo "シンボリックリンク以外の何か(存在しない場合も含む)" fi
こんな感じです
しかし変数名に日本語を使うとエラーを吐くのでやめましょう
これだけだと寂しいので解説すると
ls -F1ad ${調べたいファイル名}
これでまず
Fでファイルのタイプを名前の後ろに付け足します。シンボリックリンクだったら語尾に@がつきます
1で1行ずつ表示(ファイルの対象は1つしかないのでいらないと思いますが何となく)
aでドットから始まるファイルも対象に
dでディレクトリを指定した場合は中身を表示するのではなくそれそのものが対象に
これを~/.vimがシンボリックリンクだとして実際にやってみると
% ls -F1ad ~/.vim /home/noter/.vim@
こんな感じになります
後ろの
2>/dev/null
これはもし存在しないファイルが対象だった時などにエラーが出たら邪魔なので個人的に消します
ちなみに恥ずかしい話ですが
ls -F1ad ~/.vim > /dev/null 2>&1|grep "@$" > /dev/null 2>&1
こう書いて~/.vimがシンボリックリンクなのに
シンボリックリンクが存在しないと言われて数分悩みました
当たり前なんですがパイプで渡す予定の標準出力も捨てちゃってます
みなさんも気をつけましょう
それでは話を戻して
grep "@$" > /dev/null 2>&1
この部分はgrepで語尾が@の行だけを抜き出して出力はいらないので捨てちゃってます
$は一番後ろという意味です
if [ ${?} == "0" -a "$(ls -F1ad ${調べたいファイル名})" != "$(ls -1ad ${調べたいファイル名})" ];then echo "シンボリックリンクです" else echo "シンボリックリンク以外の何か(存在しない場合も含む)" fi
最後のここでシンボリックリンクか判定してます
条件を順番に見て行きましょう
if [ ${?} == "0" ]
grepの戻り値を判定してます
この場合だと0が見つかった。1が見つからなかった。が返るようです
詳しくはman grepのEXIT STATUSに書いてあります
if [ "$(ls -F1ad ${調べたいファイル名} 2>/dev/null)" != "$(ls -1ad ${調べたいファイル名} 2>/dev/null)" ]
ここでファイル名に最後に@が使われていた場合にきちんと動かない場合があるので
その@はls -Fでつけられたものかファイル名のものかを判定してます
これも2>/dev/nullがあるのは個人的にエラー表示は邪魔なので消してます
ちなみに間にあった-aはandという意味です
つまりさっきの2つの条件が両方とも合えば真になります
*1:一回別記事に書いたのですが、この記事に追記した方がいいかなと思って別の記事は消してここに書きました