C程序调用shell脚本

时间:2010-11-15 19:13:38

标签: c shell

我有一个小的C程序调用shell脚本myScript.sh。我得到ret的值为256.请帮助我知道系统调用出了什么问题?

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

使用64位UNIX操作系统并使用ksh shell

8 个答案:

答案 0 :(得分: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做什么,但这不可能是正确的。

答案 1 :(得分:4)

system函数通常用于* nix的方式是调用fork,然后子进程调用其中一个exec函数/bin/sh {{1然后传递给子节点中的-c的字符串,它将子进程转换为运行该命令的system程序的实例。父调用其中一个/bin/sh函数,它等待wait退出,它使用与shell脚本相同的退出状态,然后/bin/sh也返回该值。

如果查看system系统调用的手册页:

wait

您应该获得一些有关返回内容的信息以及一些可以帮助您理解它的宏函数。

main 3 wait 宏可用于测试程序是否正常退出而不是信号。正常退出涉及调用WIFEXITED(stat_val)系统调用。如果此函数返回非零值,则可以使用exit宏来获取实际返回的值。

WEXITSTATUS(stat_val)宏可用于测试程序是否以信号终止,如果是,WIFSIGNALED(stat_val)宏将返回导致终止的信号编号。

还有其他一些宏可以告诉你这个过程是停止还是继续,而不是终止,但我不认为它们对你有太大帮助,但是你可能想要研究它们。

就这种情况实际发生的情况而言,可能很难说清楚。如果WTERMSIG(stat_val)调用失败,则fork将能够返回-1并设置system以反映错误。如果errno没有失败,则可能在孩子身上发生了错误并且更难以找到。您可能有可能在您的平台上fork进行一些测试,然后才能确保您有权执行相应的文件,并设置system来反映这一点,但可能不会。

在设置errno的情况下,您应该查看perror函数以打印出错误消息。

如果失败发生在errno之后和孩子内部,那么你需要让shell告诉你更多关于发生了什么的事情,或者获取shell脚本。这可能是通过在脚本中包含fork语句,类似于在C程序中使用print语句。

您还应该查看echo函数以测试您是否有权读取和/或执行文件。

如果您使用的是Linux,那么您应该能够:

access

strace -o my_program.strace -f ./my_program

然后检查跟踪文件(在ltrace -o my_program.ltrace -f -S ./my_program 之后)以查看程序和内核相互之间的说法。 -o查看程序如何与库函数对话,而strace查看系统调用,但ltrace告诉ltrace也查看系统调用。 -S参数告诉他们在程序创建时跟踪程序的子项。

我刚注意到你说你正在使用ksh

正如我在Posix系统下提到的-f应该使用system或兼容的shell。这并不意味着/bin/sh不会运行/bin/sh来运行您的脚本(或者内核不会使用脚本文件开头的/bin/ksh行来执行此操作),但这可能是一个问题。有一些方法可以运行shell脚本,以便不使用此行来知道要使用哪个shell。最值得注意的是:

#!

句点和空间实质上是尝试将文件的文本转储到当前的shell会话中,而不是在另一个进程中运行它(这对于设置环境很有用)。如果你要这样做:

. myshell.sh

那可能是个问题。

答案 2 :(得分:2)

命令的退出状态编码为两个字节:

  • 高位字节包含退出状态。
  • 低位字节包含杀死它的信号(如果有的话)。

由于0x0100是256十进制,因此您的shell脚本退出状态1.检查您的shell脚本并确保它在成功时以状态0退出。

答案 3 :(得分:2)

从标准(重点是我的):

  

6.5.7 / 3   如果右操作数的值[>> operator]为负数或大于或等于提升左操作数的宽度,行为未定义

所以,当你这样做时

ret >>= ret;

ret < 0ret >= CHAR_BIT * sizeof (int) ......一切顺利


system函数的返回值在出错时可以为-1。

如果您的呼叫以这样的负值返回,则下一个操作ret >>= ret;(与ret = -1 >> -1;相同)会产生无意义的内容:您无法右移负数位。< / p>

当你尝试做没有意义的事情时,C可以做任何事情...... 任何事情(包括什么都不做,做你想要的,重新格式化你的硬盘,转移你的我的银行账户,让恶魔飞出你的鼻子......,...,...)

答案 4 :(得分:1)

确保您的脚本在路径中是可执行的,或者改为使用完整路径。

答案 5 :(得分:0)

没有出错。你看过文件了吗?参见:

  

返回值
         错误时返回的值为-1(例如fork(2)失败),以及   否则返回命令的状态。后一种返回状态采用wait(2)中指定的格式。   因此,命令的退出代码将是WEXITSTATUS(状态)。如果无法执行/ bin / sh,   退出状态将是退出(127)的命令。

由于256不是-1,因此呼叫没有失败。

答案 6 :(得分:0)

为什么要改变结果?只需删除行ret&gt;&gt; = ret,它就能正常工作。

答案 7 :(得分:0)

我正在使用linux,它帮助用系统调用脚本(“sh script.sh”)