-1

いくつかの RHEL 5.8 で、execve 呼び出しの問題に直面しています。ただし、execve は失敗せず、次のエラーが発生します。

/bin/bash: h: No such file or directory

C++ コードで次のように使用しています。

::fork();
.
.
.
char achWritePipeDescriptor[8], achReadPipeDescriptor[8];
snprintf(achWritePipeDescriptor, sizeof(achWritePipeDescriptor), "%d", fWritePipeDescriptor);
    snprintf(achReadPipeDescriptor, sizeof(achReadPipeDescriptor), "%d", fReadPipeDescriptor);

// fWritePipeDescriptor and fReadPipeDescriptor are integers

::execl("/bin/sh", "/bin/sh", "Launcher.sh", achWritePipeDescriptor, achReadPipeDescriptor, (char*)0);

switch(errno)
{
default:
    printf("\n Failed to launch Launcher.sh\n");
    break;
}

ここでの exec 呼び出しは失敗していませんが、上記の script.sh と対話しようとすると上記のエラーが発生しました。このプロセスの strace 出力は次のようになります。

execve("/bin/bash", ["/bin/bash", "h", "10", "6"], [/* 36 vars */]) = 0
.
.
.
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
fstat(2, 0x7fff23708910)                = -1 EBADF (Bad file descriptor)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b9d1c785000
write(2, "/bin/bash: h: No such file or di"..., 40) = -1 EBADF (Bad file descriptor)
exit_group(127)                         = ?
Process 13030 detached

ここで参照されているファイル「h」はありませんが、スクリプト名の最後の文字は「h」です。また、実行しようとしているスクリプトは予想される場所に存在し、十分な権限を持っています。

「h」がどこから来ているのかわかりません。

execve 呼び出しを次のように変更しました。

::execl("Launcher.sh", "Launcher.sh", achWritePipeDescriptor, achReadPipeDescriptor,(char*)0);

これで正常に動作しましたが、以下のコードで、別の execl 呼び出しで同様のエラーが発生しています。2 番目の exec の違いは、バイナリが異なることですが、エラーは同じままです。

これがサーバー固有の問題かどうかはわかりません。

手がかり、トラブルシューティングの手順は非常に役立ちます。

<script.sh>私の悪い、私はそれ自体がプレースホルダーであることを以前に言及するべきでした. 実行しようとしているのがシェルスクリプトであることを示しようとしました。また、ここwritefdreadfdchar*ます。ここに貼り付けたstrace出力ではっきりと見ることができます。繰り返しますが、「Launcher.sh の起動に失敗しました」というメッセージが表示されないため、ここで exec が失敗することはありません。

4

2 に答える 2

1

ここには、MikeyB によって対処された<script.sh>vs問題に加えて、別の問題があります。"script.sh"もう 1 つの問題は、writefdreadfdに渡されることexeclです。名前を考えると、それらはあるパイプの書き込み側であり、別のパイプの読み取り側であると想定しています。この場合、ポインタwritefdreadfdはなく整数です。char*

dup2一部のスクリプトがパイプを介してプログラムと通信するようにする最も簡単な方法はdup2execl. このスクリプトは、標準入力から読み取り、標準出力に書き込むだけです。これらのファイル記述子をスクリプトに渡す必要はまったくありません。

于 2012-10-31T13:28:32.037 に答える
0
execl("/bin/sh", "/bin/sh", <script.sh>, writefd, readfd, NULL);

それはうまくいかないでしょう…<script.sh>有効なC++ではありません。

次のように変更します。

execl("/bin/sh", "/bin/sh", "script.sh", writefd, readfd, NULL);
于 2012-10-31T12:10:52.970 に答える