то, как функция system
обычно работает на * Nix является то, что он называет fork
, а затем ребенок называет один из exec
функций с /bin/sh
-c
, а затем строку, которую вы передали system
, в дочерний процесс, который превращает дочерний процесс в экземпляр программы /bin/sh
, которая запускается команда. Родитель вызывает одну из функций wait
, которая ждет выхода /bin/sh
, который он выполняет с тем же статусом выхода, что и сценарий оболочки, а затем system
также возвращает это значение.
Если вы посмотрите на человека страниц для wait
системного вызова (ы):
main 3 wait
Вы должны получить некоторую информацию о том, что получает возвращается и некоторые макро функции, которые помогут вам разобраться в этом.
Макрос WIFEXITED(stat_val)
может использоваться для проверки, если программа вышла нормально, а не с сигналом. Нормальные выходы включают вызов системного вызова exit
. Если эта функция возвращает ненулевое значение, вы можете использовать макрос WEXITSTATUS(stat_val)
, чтобы получить значение, которое оно фактически вернуло.
Макрос WIFSIGNALED(stat_val)
можно использовать, чтобы проверить, была ли программа завершена сигналом, и если так, макрос WTERMSIG(stat_val)
вернет номер сигнала, который вызвал завершение.
Есть несколько других макросов, которые могут сказать вам, что процесс был остановлен или продолжен, а не прекращен, но я не думаю, что они слишком полезны для вас с этой целью, но вы можете захотеть изучить их ,
Насколько это реально происходит в этом случае, это может быть трудно сказать. Если вызов fork
невозможен, то system
сможет вернуть -1 и установить errno
, чтобы отразить ошибку. Если fork
не сбой, ошибка может произойти в ребенке и будет сложнее найти. Возможно, на вашей платформе system
может выполнить некоторые тесты перед форкированием, чтобы убедиться, что у вас есть разрешение на выполнение соответствующих файлов и установите errno
, чтобы это отразить, но, возможно, нет.
Вы должны заглянуть в функцию perror
, чтобы распечатать сообщения об ошибках в том случае, если установлен errno
.
Если сбой происходит после fork
и внутри ребенка, то вам нужно либо получить оболочку, чтобы рассказать вам больше о том, что происходит, либо получить сценарий оболочки.Это может быть включение echo
операторов в скрипт, аналогично использованию операторов печати в ваших программах на языке C.
Вы также должны изучить функцию access
, чтобы проверить, есть ли у вас разрешение на чтение и/или выполнение файлов.
Если вы используете Linux, то вы должны быть в состоянии сделать:
strace -o my_program.strace -f ./my_program
или
ltrace -o my_program.ltrace -f -S ./my_program
, а затем изучить файлы трассировки (после -o
), чтобы посмотреть на то, что программы и Ядро говорит друг другу. ltrace
смотрит, как программа разговаривает с библиотечной функцией, а strace смотрит на системные вызовы, но -S
сообщает, что ltrace также смотрит на системные вызовы. Аргумент -f
говорит им, что они должны отслеживать дочерние объекты программы по мере их создания.
Я просто заметил, что вы сказали, что вы использовали Ksh
Как я уже говорил system
в рамках системы Posix следует использовать /bin/sh
или совместимую оболочку. Это не означает, что /bin/sh
не запускает /bin/ksh
для запуска вашего скрипта (или что ядро не будет использовать строку #!
в начале файла сценария для этого), но это может быть проблемой. Есть способы запуска shell-скриптов, чтобы эта строка не использовалась для определения оболочки, которая будет использоваться. Наиболее примечательным является:
. myshell.sh
период и пространство по существу пытается сбросить текст файла в текущей сессии оболочки, а не запускать его в другом процессе (это полезно для настройки среды). Если вы должны были делать:
int x = system(". myshell.sh");
Тогда это может быть проблемой.
Post код myScript.sh, а также. Без его кода мы не сможем помочь. –
Что возвращает скрипт, если он вызван из командной строки cmd? 'MyScript.sh; Система echo $? ' – khachik
принимает символ char *, вы, конечно, имели в виду ret = system (" myScript.sh "); – Matthieu