11
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

スクリプト言語のプログラム(ruby, pythonなど)をコマンド(sh)として実行する

Last updated at Posted at 2015-09-07

スクリプト言語のプログラム(ruby, pythonなど)を、shスクリプトからexec ruby hoge.rb "$@"として呼び出す場合に考慮すべき点をまとめました。
(rubyコードの先頭行に#!/usr/bin/ruby書いて、インタプリタ起動するのとは違います)
shスクリプトがシンボリックリンクでも動作するように、スクリプト言語のあるパスを取得する必要があります。

サンプル

コマンドラインで渡された引数を標準出力に表示するrubyプログラム(echo_args.rb)を、shスクリプト(echo_args)から実行します。

ファイル構成

echo_args
|- bin/
 |  echo_args    # rubyプログラム実行スクリプト
|- lib/
 |  echo_args.rb # rubyスクリプト

ソース

echo_args.rb
ARGV.each {|s| puts s}
echo_args
#!/bin/sh

# 自身の絶対パスを取得する
ECHO_ARGS_FILE_DIRECTORY=$(cd ${0%/*} && pwd -P)

# 実行しているのはリンク?
## リンクの場合、readlinkの戻り値が変数に入る
ECHO_ARGS_SYMLINK=$(readlink "$0")
if [ -n "$ECHO_ARGS_SYMLINK" ]
then
  ECHO_ARGS_SYMLINK_DIRECTORY=$(dirname "$ECHO_ARGS_SYMLINK")
  ECHO_ARGS_FILE_DIRECTORY=$(cd $ECHO_ARGS_FILE_DIRECTORY &&
    cd $ECHO_ARGS_SYMLINK_DIRECTORY && pwd -P)
fi

# rubyプログラムのパスを取得
ECHO_ARGS_LIBRARY_DIRECTORY=$(cd $ECHO_ARGS_FILE_DIRECTORY/../lib && pwd -P)

# rubyプログラムを実行する
exec ruby "${ECHO_ARGS_LIBRARY_DIRECTORY}/echo_args.rb" "$@"

ポイント

  • 自身がリンクかどうかはreadlinkコマンドで判断する
  • 実行されたリンクが相対パスだった場合を考慮、
    自身のパスを取得して、そこを基点とする

実行例

shスクリプトが、非リンク、絶対/相対パス指定のリンク、いずれの場合も意図したとおりに動作しました。

% pwd
/Users/yampro/Dropbox/src/ruby/echo_args/bin
% ll
total 8
-rwxr-xr-x@ 1  echo_args*
★非リンクの場合(スクリプト実体)
% ./echo_args taniguchi marui
taniguchi
marui

% pwd
/Users/yampro/bin
% ll
lrwxr-xr-x   1 linka@ -> /Users/yampro/Dropbox/src/ruby/echo_args/bin/echo_args
lrwxr-xr-x   1 linkb@ -> ../Dropbox/src/ruby/echo_args/bin/echo_args
★linkaが絶対パス、linkbが相対パスのシンボリックリンク

★絶対パス指定したリンクの場合
% ./linka igarashi iguchi
igarashi
iguchi

★相対パス指定したリンクの場合
% ./linkb kondo makino
kondo
makino

参考にしたもの

  • Homebrewの実行スクリプト

メモ

  • GNU版のreadlinkは-fでリンク元のフルパスは取得できるが、
    BSD版(Mac)にはないので使わなかった
    (使えば、分岐なしにシンプルに書ける)
  • $0: 実行しているコマンドの実行パス(相対)
  • $@: シェルスクリプトに渡されたすべての引数
  • exec: 子プロセスを生成せずに、コマンドを実行する
11
13
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?