ここから本文です

シェル初心者です。cygwin環境下で、C言語のプログラムからシェルスクリプトを呼び...

hir********さん

2012/12/1020:19:38

シェル初心者です。cygwin環境下で、C言語のプログラムからシェルスクリプトを呼び出して、フォルダを削除するにはどうすればよろしいのでしょうか?全くうまく行かず、困っています。
よろしくお願いします。

#include<stdio.h>

main(){

int i,j;
char filepath[256];

sprintf(filepath, "./output/case_1");

system("./header_files/folder_del.sh $filepath &");

return(0);
}

以下シェルスクリプト

#!/bin/sh

read filepath

rmdir $filepath

exit 0

以下実行結果

$ ./test
./header_files/folder_del.sh: line 2: $'\r': コマンドが見つかりません
': not a valid identifier.sh: line 3: read: `filepath
./header_files/folder_del.sh: line 4: $'\r': コマンドが見つかりません
rmdir: `\r' を削除できません: No such file or directory
./header_files/folder_del.sh: line 6: $'\r': コマンドが見つかりません

閲覧数:
629
回答数:
2

違反報告

ベストアンサーに選ばれた回答

ad4********さん

2012/12/1021:57:54

シェル初心者というか、Cも初心者だな。シェルとCの変数をごっちゃにしない。

$filepathはシェルが環境変数を展開するものだ。C言語は文字列中の$filepathは展開してくれんし、Cのfilepath変数にデータを設定しただけでは環境変数には何の影響もない。どうしても環境変数に設定してシェルスクリプトを呼び出したいならsetenv関数を使うこと。

ついでに言っておくと、sprintfの使い方も間違っている。今は固定の文字列をfilepathに設定しているだけだからいいが、もしargv[1]とかを設定しようとすればあっというまにセキュリティホールのできあがりだ。sprintfを使いたいなら

sprintf(filepath, "%s", argv[1]);

のような使い方が正しい。今の場合は文字列をfilepathに設定するだけだから、

strcpy(filepath, argv[1]);

の方が一般的。

そうでなく、とにかくパラメータをシェルスクリプトに渡したいなら、最初の回答者さんのように$1を使ったほうが楽。ただ、すでにsprintfを使っているから、strcatでちまちまつなぐより、一気に

char cmd[256];
sprintf("./header_files/folder_del.sh %s &", filepath);

とやっちまった方が楽だろう。

いずれの場合もバッファオーバーランに注意すること。この例の場合はfilepathの文字数が制限されているからそれにコマンド文字列の文だけ+αした領域をとっておけばよいが、より安全に書くならasprintfなどを使うこと。asprintf使うときはfree忘れるなよ。

シェルスクリプトのほうはreadコマンドは標準入力からの読み込みだろう。C言語から呼び出したシェルスクリプトに本当にreadで標準入力からファイル名を渡したいのなら、pipeを使って標準入力を作ってやらにゃあかん。ということはforkして親プロセス側で(略・・・初心者には多分ムリ。

C言語とのインターフェースも矛盾があって、意図としてはfilepathを設定してそれをシェルスクリプトで使おう、ということなんだろうが、このシェルスクリプトではきちんとfilepathを設定してもreadで標準入力を読み込んで、そのデータでfilepathを上書きしちゃうぞ?

それから \r がいっぱい出てくるのは、改行コードがCRLFになっているシェルスクリプトをバイナリモードで読んでるからだな。シェルスクリプトの改行コードをLFにすれば解決する。これはCygwinではよくある現象。覚えておくといい。

とりあえずシェルスクリプト単体で動作を確認するべし。今のシェルスクリプトだと、実行するととりあえず入力待ちになっちまうはずなんだが。それと、なんでCから呼び出そうと思ったんだ?

質問した人からのコメント

2012/12/17 09:05:58

降参 質問内容だけではなく、その他注意しなくてはいけない点など、多くのアドバイスをありがとうございました。

ベストアンサー以外の回答

1〜1件/1件中

kpgcさん

2012/12/1020:59:54

#include<stdio.h>
#include<string.h>

main(){

int i,j;
char filepath[256];
char cmd[256];

sprintf(filepath, "./output/case_1");


strcpy(cmd,"./header_files/folder_del.sh ");
strcat(cmd,filepath);
strcat(cmd," &");
system(cmd);

return(0);
}

#!/bin/sh

rmdir $1

exit 0

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる