サーバー上にあるRubyで書いたスクリプトを自動で定期実行できるようにXserverのCronで設定していた。
【やりたかったこと】
実行時の出力内容を指定のフォルダとcsvファイルに保存し、フォルダ内に同名csvがなければ作る。
【状況】
Cronで実行する前にSSH接続で直接実行すると問題なく動作し、フォルダの指定やファイル作成は期待した通りに動いてくれる。ただCronで実行すると”initialize’: No such file or directory -“エラーとなり停止してしまう。
【解決】
保存したいファイルパスを相対パスではなく絶対パスにする。
解決策候補
・絶対パスをそのまま記述
・Cron実行時にディレクトリを移動させる
・File.expand_path()を使う
SSHでコマンドを叩く時はその動いてほしいスクリプトのあるディレクトリに移動してから実行していため実行時のカレントディレクトリとの関係で相対パスでもいけるが、Cron実行時にはカレントディレクトリが異なるため絶対パスにする。
ただし絶対パスだとローカル環境で書いたものとXserverに挙げた時とでいちいち適したパスに変更する必要があるのと今後の常用も考慮してFile.expand_path()を使うことにした。
class File expand_path(path, default_dir = ‘.’) -> String https://docs.ruby-lang.org/ja/2.0.0/class/File.html#S_EXPAND_PATH
※リファレンスマニュアルは現在利用しているRubyのバージョンに合わせてRuby2.0.0を添付
class File expand_path(path, default_dir = ‘.’) -> String
https://docs.ruby-lang.org/ja/2.0.0/class/File.html#S_EXPAND_PATH
path を絶対パスに展開した文字列を返します。 path が相対パスであれば default_dir を基準にします。
先頭の ~ はホームディレクトリ(環境変数 HOME が使われます)に、 ~USER はそのユーザのホームディレクトリに展開されます。
「RubyのFile.expand_path(‘相対パス’, FILE)の意味 https://maeharin.hatenablog.com/entry/20130104/p1
自分の場合実行ファイルとフォルダ(hogehogefolder)の階層が同じため以下のようになる。
File.expand_path(‘../hogehogefolder/hoge.csv’, __FILE__)
を例のファイルパスの中に差し込んであげると良い。これは__FILE__で現在実行中のファイルのパスを返す。ただし、実行ファイルそのものの名前は保存先ファイルには不要であるため、../であえて一度上の階層に移動してからフォルダー以下csvファイルの名前を記入するとCronでも上記エラー文が表示されずに成功した。
パスは環境毎で変わってしまうため絶対パスをこの方法でローカル開発時との差分を減らして変更の手間やエラーを無くす。また手動実行時と比べてCronや自動実行などのときに果たしてそれが「どこで」実行されるのかの意識をこれから持つようにする。