2008年11月27日(木) [長年日記]
- 腰が痛いのはもう治った。
■ [shell][unix][howto] シェルスクリプトファイル自身の格納ディレクトリの絶対パスを得る
毎回同じことを調べている。
#!/bin/sh cd `dirname $0` d=`pwd` echo $d
で大体うまくいくが、パス中にシンボリックリンクがあったりファイル自身がシンボリックリンクだと、リンク先ファイルとは異なる絶対パスが得られてしまい困ることがある。格納ディレクトリからの相対パスで別のファイルを探したい時とか。
これを解決する簡単でポータブルな方法はなさそうだが、最近のLinuxだと readlink というコマンドがあるようで、これを使うと簡単に絶対パスを取得できた。
readlink は -f オプションを使うと
% ln -s /usr/bin/gcc link % readlink -f link /usr/bin/gcc % readlink -f /usr/bin/gcc /usr/bin/gcc
のようにリンクがあろうとなかろうと絶対パスを出力してくれるようなので、
#!/bin/sh my_path=`readlink -f $0` cd `dirname $my_path` d=`pwd` echo $d
のようにすればよさそう。
(追記)
今見ると上のスクリプトはおかしい。readlinkが絶対パスを出力してくれるならcdやpwdをする必要はなくて
#!/bin/sh my_path=`readlink -f $0` d=`dirname $my_path` echo $d
でいいはず。
(追記2)
少なくともbashでは、スクリプト起動直後の $_ にコマンドの絶対パスが設定されていることを知った。
- 特殊パラメータ (bashのman)
- 上はリンク切れ。次のURLへ移行したみたい。http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html#lbAT
ただし、readlinkのようにシンボリックリンクを辿ってはくれない。また、$_ に絶対パスが設定されているのはスクリプトの起動直後だけだということに注意が必要。
$ cat myname.sh #!/bin/bash echo ' $_ :' $_ echo ' $0 :' $0 echo ' readlink:' `readlink -f $0` echo aaa > /dev/null echo ' $_ :' $_ $ ln -s myname.sh oreore.sh $ ./myname.sh $_ : /home/kenichi/tmp/./myname.sh $0 : ./myname.sh readlink: /home/kenichi/tmp/myname.sh $_ : aaa $ ./oreore.sh $_ : /home/kenichi/tmp/./oreore.sh $0 : ./oreore.sh readlink: /home/kenichi/tmp/myname.sh $_ : aaa
■ [shell][unix][howto] パイプの途中で行を追加する
パイプを使ってテキストを変換していくとき、途中で新しい行を追加したくなった。が、やり方をなかなか思いつかない。
awkのENDを使えばできた。
% echo "ore\nboku" | sort | awk '{print} END {print "omae"}' boku ore omae
awk便利だな。awk使うならパイプ使わず全部awkで処理すればいいじゃない、それならperlでもいいじゃんか、という話になる。うーむ。
ところで、「man awk」だと英語のマニュアルが表示されるが「man gawk」とすると日本語訳(左はリンク切れ。こっちへ移行したみたい。)を読めることに気づいた。
■ [ruby] JRubyが実行できなかった
JRubyを使おうとここからダウンロードして展開したが、
% jruby Exception in thread "main" java.lang.NoClassDefFoundError: org/jruby/Main Caused by: java.lang.ClassNotFoundException: org.jruby.Main at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
のようになり実行できなかった。
色々調べた結果、libディレクトリにあるべき jruby.jar というファイルが無いのが原因の模様。何故無いのか。
その原因は、おれのダウンロードしたファイルが jruby-src-1.1.5.tar.gz だったため。これだと、srcなので自分でビルドしないといけないみたい。jruby-bin-1.1.5.tar.gz というファイルをダウンロードし直したら、libに jruby.jar が存在し普通に実行できた。
配布ディレクトリにファイルが多すぎて、どれをダウンロードすればいいのかが分かりにくいのだ。気を付けろ。
■ やること
- お香典
洗顔O2ケア- 5000円
行を追加ですが別解で<br>echo hoge | ( cat -; echo fuga )<br>の方が軽いと思います。
なるほど、このようにする方がよさそうです。ありがとうございます。<br>これはbashのマニュアルに「Compound Commands」として書かれている機能を使ったことになりそうですね。ちゃんと理解できていない気がするので、後でまた考えてみます。