OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

C++でシェルを起動

  • すぐに回答を!
  • 質問No.100382
  • 閲覧数2487
  • ありがとう数4
  • 気になる数0
  • 回答数8
  • コメント数0

UNIX C++でシェルを起動する方法を教えてください。
よくわかっていないので、質問の仕方もあいまいですが、お願いします。
通報する
  • 回答数8
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.8
レベル14

ベストアンサー率 50% (1122/2211)

> プログラムで上記のようにして実行しても、親プロセスが死んじゃうと、一緒に死んじゃうみたいです。

変だなあ。試してみたんだけど、大丈夫なんだよなあ。試したソースと
スクリプトを。

親のソース。

#include <stdlib.h>

int main()
{
  system("nohup a.sh &");
  return 0;
}

呼ばれるスクリプト。

#!/usr/bin/sh

sleep 5
echo "aaa" >> aaa.txt

で、chmod u+x a.sh して、a.sh に実行権限をつけて、

$ a

ってして、5秒のうちに急いでログアウトする。子プロセスの a.sh は
中断されず aaa.txt に出力されている。

system() に渡すコマンドラインから nohup を外すと、子プロセスが
中断されることも確認。

また、ログインシェルを csh にしたら nohup をつけなくても、
子プロセスが中断されないことも確認。

# 意地になってます (^^;
補足コメント
noname#794

ためしに、スクリプトを上記のやつで実行してみたら、ちゃんと動いてるみたいです。
シェルの中身が悪いんですかね。
よくわかりませんが、とりあえず、プログラムのほうは大丈夫みたいです。
ありがとうございました。
投稿日時 - 2001-07-06 21:11:55
-PR-
-PR-

その他の回答 (全7件)

  • 回答No.2
レベル13

ベストアンサー率 37% (419/1115)

確かに少々あいまいですので補足をお願いいたします。 ここで言うシェルとは仮想端末としてのシェルですか? それともシェルスクリプトですか? (後者ではないかと予想はしていますが) それによって回答は変わってくると思いますので。 ...続きを読む
確かに少々あいまいですので補足をお願いいたします。
ここで言うシェルとは仮想端末としてのシェルですか?
それともシェルスクリプトですか?
(後者ではないかと予想はしていますが)
それによって回答は変わってくると思いますので。
補足コメント
noname#794

シェルスクリプトのほうです。
投稿日時 - 2001-07-06 11:52:10
  • 回答No.1
レベル14

ベストアンサー率 50% (1122/2211)

何も考えなくて良いのが system() かな。 #include <stdlib.h> system("ls -la"); って感じ。 他には、fork()+exec系の関数 とか popen() を使う方法もあります。 system() に比べて、細かくコントロールできるとか、出来ることが 増えていると考えてください。 オンラインマニュ ...続きを読む
何も考えなくて良いのが system() かな。

#include <stdlib.h>

system("ls -la");

って感じ。

他には、fork()+exec系の関数 とか popen() を使う方法もあります。
system() に比べて、細かくコントロールできるとか、出来ることが
増えていると考えてください。

オンラインマニュアルにも載ってますよ。
お礼コメント
noname#794

早速回答ありがとうございます。
ちょっと調べてみたいと思います。
投稿日時 - 2001-07-06 11:51:55
  • 回答No.3
レベル13

ベストアンサー率 37% (419/1115)

補足読みました。 シェルスクリプトと言うことでしたらa-kumaさんがご回答された様に、 system("xxx"); ・・・xxxはシェルスクリプト名、必要ならばパス付きで。 または、実行権が付いていなければ system("sh xxx"); とかでしょうか。 また、こちらもa-kumaさんが書かれていますが、子プロセスとして動作させ ...続きを読む
補足読みました。
シェルスクリプトと言うことでしたらa-kumaさんがご回答された様に、

system("xxx"); ・・・xxxはシェルスクリプト名、必要ならばパス付きで。

または、実行権が付いていなければ

system("sh xxx");

とかでしょうか。
また、こちらもa-kumaさんが書かれていますが、子プロセスとして動作させたり、プロセスをスクリプトに空け渡して実行させるとしたらfork + exec系を使用することになると思います。
お礼コメント
noname#794

なんだか、難しそうですね。
ちょっと挑戦してみます。
投稿日時 - 2001-07-06 16:55:11
  • 回答No.4
レベル13

ベストアンサー率 37% (570/1525)

ちょっと確認します。 1.シェルスクリプトはエラーを起こす可能性があるか? 2.シェルスクリプトはエラーの場合それを報告するか? 3.エラーの報告はstderrか?プロセスステータスか? 4.起動するプログラム(親)はシェルスクリプト(子)の終了を待つか?同時に動作するか? 仕様によってはsystem()では役立たずの場合もあります。 完全な制御が必要ならfork()+exec() ...続きを読む
ちょっと確認します。

1.シェルスクリプトはエラーを起こす可能性があるか?
2.シェルスクリプトはエラーの場合それを報告するか?
3.エラーの報告はstderrか?プロセスステータスか?
4.起動するプログラム(親)はシェルスクリプト(子)の終了を待つか?同時に動作するか?

仕様によってはsystem()では役立たずの場合もあります。

完全な制御が必要ならfork()+exec()でしょう。
場合によってはwait()を使ったりsignal()の制御も必要になります。
補足コメント
noname#794

1~3についてはエラーを起こす可能性はありません。
4については、親プログラムとシェルスクリプトは同時に動作させたいと思ってます。

fork()+exec()の使い方がわからないのですが、
具体的にどういうふうに使うのでしょうか?
投稿日時 - 2001-07-06 13:28:30
  • 回答No.6
レベル14

ベストアンサー率 50% (1122/2211)

> systemを使った場合、もし、シェルスクリプト(子)が起動中に親プログラムが > 終了してしまったら、シェルのほうは一緒に死んでしまうのでしょうか これは unix でのプロセスの扱い方の話なので、呼び方には関係ないです。 代表的なところでいうと、sh は端末が切り離されたときに HUP シグナルが 発生します。そのスクリプトが sh で動くものであれば、親プロセスが ...続きを読む
> systemを使った場合、もし、シェルスクリプト(子)が起動中に親プログラムが
> 終了してしまったら、シェルのほうは一緒に死んでしまうのでしょうか

これは unix でのプロセスの扱い方の話なので、呼び方には関係ないです。

代表的なところでいうと、sh は端末が切り離されたときに HUP シグナルが
発生します。そのスクリプトが sh で動くものであれば、親プロセスが
端末から切り離されてないと、親が終了したときには、その子供に SIGHUP が
通知されます。何も考えずに作っていれば子プロセスも終了します。

それを回避するには nohup コマンドを使います。

csh は HUP を含めたキーボードから発生するシグナルはバックグラウンドジョブ
には通知されません。なので、親プロセスが終了しても、子プロセスは
動きつづけます。
補足コメント
noname#794

回答ありがとうございます。
nohupコマンドっていうのがあるのですね。

ちょっとプログラムに組み込んでみたのですが、コンパイルエラーが出ます。
"「nohup」にはプロトタイプが必要です"というエラーです。
あと確認したいのですが、このコマンドは引数はひとつしか渡せない??
この認識はあってますか?
投稿日時 - 2001-07-06 19:15:24
  • 回答No.5
レベル14

ベストアンサー率 50% (1122/2211)

> 親プログラムとシェルスクリプトは同時に動作させたいと思ってます ということは、シェルスクリプトに起動をかけたら、その終了を待たずに プログラムは他の処理を続けて良い、ということですね。であれば、   system("スクリプト &"); と、バックグラウンドジョブで起動すればOK。 > fork()+exec()の使い方がわからない ...続きを読む
> 親プログラムとシェルスクリプトは同時に動作させたいと思ってます

ということは、シェルスクリプトに起動をかけたら、その終了を待たずに
プログラムは他の処理を続けて良い、ということですね。であれば、

  system("スクリプト &");

と、バックグラウンドジョブで起動すればOK。


> fork()+exec()の使い方がわからないのですが

fork() は以下のように使います。

  pid_t pid;
  pid = fork();
  if (pid == 0) {
    execl("スクリプト", NULL);
  } else if (pid < 0) {
    /* fork() に失敗! */
  }

exec系の関数はいろいろありますので、man を参照してください。
例えば、私が最初に挙げたような ls -la をしたければ、execl() なら

execl("/usr/bin/ls", "-la", NULL);

と使います。execv() なら

char *argv[3] = {"/usr/bin/ls", "-la", NULL};
execv("/usr/bin/ls", argv);

と使います。

execle() と execve() は、更に環境変数の指定が出来ます。
execlp() と execvp() は、最初の引数に "/" が入っていなければ、
環境変数 PATH を利用した検索も行ないます。例えば、

execlp("ls", "-la", NULL);

という感じ。
補足コメント
noname#794

systemを使った場合、もし、シェルスクリプト(子)が起動中に親プログラムが終了してしまったら、シェルのほうは一緒に死んでしまうのでしょうか。
できれば、子は親に関係なく起動していてほしいのですが。
その場合はfork()+exec()のほうで起動すればなんとかなるものなのでしょうか。
投稿日時 - 2001-07-06 16:56:19
  • 回答No.7
レベル14

ベストアンサー率 50% (1122/2211)

> コンパイルエラーが出ます nohup って、コマンドであって、関数ではないです。   system("nohup スクリプト &"); です。スクリプトには、実行権限をつけておいてください。 ...続きを読む
> コンパイルエラーが出ます

nohup って、コマンドであって、関数ではないです。

  system("nohup スクリプト &");

です。スクリプトには、実行権限をつけておいてください。
お礼コメント
noname#794

回答ありがとうございました。
コマンドラインでコマンドを実行するときはいいみたいなのですが、
プログラムで上記のようにして実行しても、親プロセスが死んじゃうと、一緒に死んじゃうみたいです。
他の方法を試してみたいと思います。
投稿日時 - 2001-07-06 20:11:10
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ