2017-03-10 4 views
1

Fortranプログラムでsystem call("action")ルーチンを使用して外部コマンドを実行しています。コマンドが呼び出されたらシェルを終了したいと思います。 Iが結合 サンプルコードは、次のとおりFortranからシェルを閉じる

program ai 
implicit none 
integer :: i 

i=1 
if (i.eq.1) then 
    call system("exit") 
end if 

end program ai 

IはCALL EXECUTE_COMMAND_LINEでも試みたが、結果は同じであり、私が働いていたシェルを閉じることができません。シェルを閉じるには、手でコマンドexitをタイプする必要があります。なぜこのコマンドがうまくいかないのでしょうか?たとえば、mkdirの場合、gnuplot ..が機能しますか?

ありがとうございます!

+0

"なぜ" - システム( "exit")は**完全に新しいシェル**を起動し、そのシェルで 'exit'を実行するためです。これまで実行していたシェルの状態は変更されません。 –

+0

私はそれがうまくいくかどうかはわかりません。このプログラムを実行すると、このプログラムはシェルの「子」になります。また、 'system'呼び出しを行うとプログラムの'子 'になります。 – chw21

+0

これは、 'system(" cd/")を使用しても効果がない理由です:関数が返ってくるまでに、あなたが変更した状態のシェルはすでに実行を終えて終了します。 –

答えて

1

Fortranプログラムはシェルの子であり、systemコマンドで呼び出されたものはプログラムの子であるため、あなたが望むほど単純ではありません。

1つの考え方は、親シェルを強制終了するためにfortran KILLサブルーチン(明らかに関数として存在します)を使用することです。しかし、これはそのPIDプログラムに与えることを親シェルが必要です。

$cat my_kill.f90 
program my_kill 

    implicit none 
    character(len=32) :: cPID 
    integer :: PID 
    call getarg(1, cPID) 
    read(cPID, *) PID 
    call KILL(PID, 9) 

end program my_kill 

$ gfortran -o my_kill my_kill.f90 
$ ./my_kill $$ 

これは、その後、終了することでしょう呼び出すシェルにハードキル信号を送信する必要があります。 (私は3(QUIT)や15(TERM)のような柔らかいkillシグナルで試しましたが、どちらもうまくいきませんでした。おそらく、シェルにまだ子供(つまりFortranプログラム自体)があったからです。

もちろん、プログラムは$$オプションで起動する必要があり、シェルスクリプトは元のシェルの子プロセスで実行されるため、これをシェルスクリプトに入れることもできません。

あなたのプログラムが標準出力に任意の出力を生成しない場合、あなたはまた、それだけで標準出力へexitを印刷行い、その後でシェル内からそれを呼び出すことができます($記号を含む)

$(<your program>) 

+1

'kill 'は標準のFortranの一部ではなく、使用可能なコンパイラと使用可能なライブラリによってその可用性が決まることに注意してください。 –

+0

同様に、OPシステムは標準ではなく、その動作はコンパイラやOS、OSによって異なります。 –

0

system()は、新しいシェルを作成し、実行するコマンドを与えます。プログラムを起動した既存のシェルにコマンドを与えることはできません。

つまり、gfortranにはKILLコールがあります。あなたが親シェルのPIDを持っていた場合(例えば、getppid() C関数を呼び出すことなど)、そのメカニズムを介して終了するように要求することができます。

関連する問題