(Linux入門はコチラ→中級者のためのLinuxコマンド入門)
ある拡張子のファイルが存在するかどうか確認したいだけなのに、testコマンドって使えないですよね。
takk~$ ls 1.bk 2.bk 3.bk takk~$ test -e *.bk bash: test: 引数が多すぎます takk~$
ワイルドカードでこのように展開されるからですね。
takk~$ test -e 1.bk 2.bk 3.bk
どうすれば回避できるでしょうか。
lsとheadを使う方法だと、ファイルが存在する場合はうまく行きます。
takk~$ test -e `ls *.bk | head -1` takk~$ echo $? 0 ~$
存在しない場合は、lsでエラーとなります。
takk~$ test -e `ls aaaa | head -1` ls: 'aaaa' にアクセスできません: そのようなファイルやディレクトリはありません takk~$
エラーの出力をどうにかすれば使えそうですが、そもそもlsとheadの結果でtestへの引数を作っているので、これも使えません。結果が0、つまりファイルが見つかったことになってしまいます。
takk~$ test -e `ls aaaa 2>/dev/null | head -1` 0 takk~$
findでも同様です。
takk~$ test -e `find -name aaaa | head -1` 0 takk~$
いっそのことtest -eや、test -fコマンドを諦めてしまう方法や、ワイルドカードで展開される分だけfor文で回してやろう、なんて強引にtestコマンドにこだわる方法もあります。
-zを使って文字列長でのチェック。結果は逆転します。
takk~$ test -z `find -name aaaa| head -1`;echo $? 0 takk~$ test -z `find -name '*.bk' | head -1`;echo $? 1 takk~$
for文で全部回してしまう方法。
takk~$ for i in *.bk;do test -e $i;done;echo $? 0 takk~$ for i in aaaa;do test -e $i;done;echo $? 1 takk~$
でも、test -eで、すっきり存在チェックしたいだけなのに、lsやfindやheadやforなどに頼っていたら本末転倒でしょう。
要は、引数を限定するだけでよいので、カスタマイズしたtest -eコマンドをつくれば良いです。関数を作ってみましょう。
takk~$ test-e(){ > test -e $1 > } takk~$
これでtest -eを使いたいときは、test-eと書けば、ワイルドカードが使えるようになります。
takk~$ ls 1.bk 2.bk 3.bk takk~$ test-e *.bk takk~$ echo $? 0 takk~$ test-e aaaa takk~$ echo $? 1 takk~$
コメント
I see your blog needs some unique articles. Writing manually is time consuming, but there is solution for this.
Just search for; Masquro’s strategies