2010-11-15 2 views
3

У меня есть небольшая программа на C, вызывающая сценарий оболочки myScript.sh. Я получаю значение ret как 256. Пожалуйста, помогите мне узнать, что пошло не так с системным вызовом?C вызов вызова оболочки сценарий

int main() 
{ 
int ret; 
ret = system (myScript.sh); 
ret >>= ret; 
if (ret != 0) 
{ 
    printf("ret is [%d]",ret); 
} 
} 

Работа на 64-разрядной UNIX операционной системы и с помощью КШ оболочки

+0

Post код myScript.sh, а также. Без его кода мы не сможем помочь. –

+0

Что возвращает скрипт, если он вызван из командной строки cmd? 'MyScript.sh; Система echo $? ' – khachik

+0

принимает символ char *, вы, конечно, имели в виду ret = system (" myScript.sh "); – Matthieu

ответ

4

то, как функция 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"); 

Тогда это может быть проблемой.

5

В моей системе man system говорит:

The system() function returns the exit status of the shell as returned by 
waitpid(2), or -1 if an error occurred when invoking fork(2) or 
waitpid(2). A return value of 127 means the execution of the shell 
failed. 

страница waitpid человек описывает набор макросов таких как WEXITSTATUS(), которые извлекают фактический код выхода из возвращаемого значения.

Я не совсем уверен, что вы собираетесь делать с ret >>= ret, но это не может быть правильно.

+0

+1 для упоминания как waitpoid(), так и WEXITSTATUS() (и друзей). Но почти -1, не говоря уже о том, что система() вообще не является хорошей идеей. –

0

Ничего не случилось. Вы читали документацию? См:

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Возвращаемое значение -1 в случае ошибки (например, вилка (2) не удалось), и статус возвращение команды в противном случае. Этот последний статус возврата находится в формате, указанном в ожидании (2). Таким образом, код выхода команды будет WEXITSTATUS (статус). В случае, если/bin/sh не может быть выполнен, будет иметь статус выхода из команды, выполняющей выход (127).

Поскольку 256 не равно -1, звонок не сработал.

+0

Этот сценарий myScript.sh должен создать файл, который не создан. Я не получаю возвращаемое значение 256 –

+0

256 unsigned -1 – Falmarri

+0

Итак, вы имели в виду, что статус выхода был -1 –

0

Почему вы изменяете результат? Просто удалите строку ret >> = ret, и она будет работать.

+0

Тогда плакат получит 512, что имеет какой-то смысл как 'waitpid (2)' status code ... как это связано с статусом выхода сценария оболочки? –

+0

О, я вижу, где я был неправ. Виноват. – 2010-11-15 19:34:29

+0

Er, 256. Тем не менее. –

1

Убедитесь, что ваш скрипт является исполняемым и находится на пути, или используйте полный путь.

+1

Действительно, я предполагаю, что OP используется для '.' В 'PATH', что является действительно плохим идеей. –

2

Статус выхода команды кодируется как два байта:

  • Байт высокого порядка содержит статус выхода.
  • Байт младшего разряда содержит сигнал, который его убил (если есть).

Поскольку 0x0100 имеет 256 десятичных знаков, ваш сценарий оболочки завершен со статусом 1. Просмотрите свой сценарий оболочки и убедитесь, что он завершает работу со статусом 0, когда он успешно завершен.

+0

Если напечатанное значение 'ret' равно 256, то фактическое (предварительно сдвинутое) значение возврата равно 512 -> 0x0200, оболочка выходит со статусом 2. Более-менее то же самое. –

+0

@Conrad: Shifting 256 >> 256 - нет-op, так как расстояние сдвига обычно принимается по mod wordsize (32). Итак, это 256 >> 0. –

+0

О, я чувствую себя немым - неправильно читаю его код. Сожалею! –

2

от стандартного (курсив мой):

6.5.7/3 Если значение правого операнда [от оператора >>] является отрицательным или больше или равна ширине продвинутого левого операнда поведение не определено.

Так что, когда вы делаете

ret >>= ret; 

и ret < 0 или ret >= CHAR_BIT * sizeof (int) ...что-то идет


Возвращаемое значение функции system может быть -1 в случае ошибки.

Если ваш вызов возвращается в таком отрицательном значении, следующая операция ret >>= ret; (то же, что и ret = -1 >> -1;) приводит к чему-то, что не имеет значения: вы не можете сдвигать вправо на отрицательное количество бит.

Когда вы пытаетесь сделать что-то без смысла, C разрешено что-либо делать ... ничего вообще (в том числе ничего не делать, делать то, что вы ожидаете, переформатировать жесткий диск, перенести свой банковский счет на мой , что делает демоны вылетают нос, ..., ..., ...)

+0

Не могли бы вы прокомментировать –

+0

@Sachin: прочитайте [этот вопрос и ответ] (http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior), пока я редактирую свой ответ :-) – pmg

+0

Спасибо PMG, мне нравятся формулировки :) –

0

Я работаю на Linux, и это помогло вызвать скрипт с системой («ш script.sh»)

Смежные вопросы