我有一个小的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
system
函数通常在* nix上运行的方式是它调用fork
然后子进程调用其中一个exec
函数和/bin/sh
-c
然后调用你传递给子进程system
的字符串,这会转换子进程进入运行该命令的/bin/sh
程序的实例。 父调用wait
函数之一等待/bin/sh
退出,它使用与shell脚本相同的退出状态,然后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
以反映该情况,但可能不会。
在errno
的情况下,您应该查看perror
函数以打印出错误消息。
如果失败发生在fork
之后和子fork
内,那么你需要让shell告诉你更多关于发生了什么,或者获取shell脚本。 这可以通过在脚本中包含echo
语句,类似于在C程序中使用print语句。
您还应该查看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
正如我所提到的,Posix system
下的系统应该使用/bin/sh
或兼容的shell。 这并不意味着/bin/sh
不会运行/bin/ksh
来运行你的脚本(或者内核不会使用脚本文件开头的#!
行来执行此操作),但它可以是个问题。 有一些方法可以运行shell脚本,以便不使用此行来知道要使用哪个shell。 最值得注意的是:
. myshell.sh
句点和空间实质上是尝试将文件的文本转储到当前的shell会话中,而不是在另一个进程中运行它(这对于设置环境很有用)。 如果你要这样做:
int x = system(". myshell.sh");
那可能是个问题。
在我的系统上, 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
做什么,但那不可能是正确的。
命令的退出状态编码为两个字节:
由于0x0100是256十进制,因此shell脚本退出状态1.检查shell脚本并确保它在成功时以状态0退出。
从标准(重点是我的):
6.5.7 / 3如果[操作符]的右操作数的值为负或大于或等于提升的左操作数的宽度, 则行为未定义 。
所以,当你这样做的时候
ret >>= ret;
并且ret < 0
或ret >= CHAR_BIT * sizeof (int)
......任何事情都会发生
错误时, system
函数的返回值可以为-1。
如果你的呼叫以这样的负值返回,则下一步操作ret >>= ret;
(与ret = -1 >> -1;
)会产生一些没有意义的东西:你不能右移一个负数位。
当你尝试做没有意义的事情时,C可以做任何事情...... 任何事情 (包括什么都不做,做你期望的事情,重新格式化你的硬盘,把你的银行账户转移到我的,让恶魔飞出你的鼻子,......,......,...)
确保您的脚本在路径中是可执行的,或者使用完整路径。
什么都没有出错。 你看过文件了吗? 看到:
返回值
错误时返回的值为-1(例如fork(2)失败),否则返回命令的返回状态。 后一种返回状态采用wait(2)中指定的格式。 因此,命令的退出代码将是WEXITSTATUS(状态)。 在无法执行/ bin / sh的情况下,退出状态将是退出(127)的命令的退出状态。
由于256不是-1,因此呼叫没有失败。
为什么要改变结果呢? 只需删除行ret >> = ret,它就可以了。
我正在使用linux,它帮助用系统调用脚本(“sh script.sh”)
以上就是c/c++开发分享C程序调用shell脚本相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/559962.html