2012-12-02

Fortran で call system() するときに変数 (variable) を渡す方法

たとえば、do i=1,100 というループを回していて、各ステップごとに毎回 mkdir i をしたい、しかも 1, 2, ... ではなく 001, 002, ... というフォルダ名で作成したい、ということがある。というかあった。無理か?と思ったが、できた。
Variables as arguments in Fortran 77
http://www.linuxforums.org/forum/programming-scripting/154686-variables-arguments-fortran-77-a.html
つまり call system() を使うことは使うが、文字列を用意して、そこにコマンドも含めて何もかも内部入出力で書き込んでしまうという力技。

具体的には、

program test
  implicit none
  integer :: i
  character(len=72) :: command
  !! -----------------------------

  do i=1,100
    write(command,"('mkdir ',i3.3)") i !! コマンドごと書き込む
    call system(command) !!
  enddo

  stop
endprogram test

ということ。

自分は実際には、mkdir_if_not_exist.sh という、そのディレクトリがあるかどうかを調べてないときだけ作るスクリプトを作って、それを呼び出している。それの中身はこんな感じ:

mkdir_if_not_exist()
{
  echo -n "Checking if $1 directory exists... "
  if [ ! -d $1 ] ; then
    echo -n "... the directory does not exist ... Making a directory $1... "
    mkdir $1
    echo "... done."
  else
    echo "... the directory already exists."
  fi
}

これの参照元は、いろんなページを参考にした気がするがメモるの忘れてたかも…(はてブには残ってるだろうが)。まぁこの程度なら著作物性はなさそうなのでいいかな…?

なお、シェルスクリプトファイルを置いているのは実行ファイル(a.out 的な)よりも一つ下の ./src の中であり、また、ディレクトリを作りたいのは ./output の下なので、上記の内部入出力 write 文のところは実際には、

  write(command,"('sh ./src/mkdir_if_not_exist.sh ./output/',i3.3)") i !! コマンドごと書き込む

という感じにしている。

No comments: