LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 995|回复: 13

求助:关于system()

[复制链接]
发表于 2005-9-2 21:48:59 | 显示全部楼层 |阅读模式
需要在程序中调用shell命令,应该是用这个函数吧?不过当命令执行出错的时候这个函数仅返回一个非零的整型错误代码。请问在程序中用什么方法可以获取这个错误代码所代表的错误信息(String)?

谢谢!
发表于 2005-9-2 23:55:10 | 显示全部楼层
man system
man 2 wait

那个值就是wait的return status
回复 支持 反对

使用道具 举报

发表于 2005-9-3 00:51:45 | 显示全部楼层
man system
查找RETURN VALUE
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-9-4 10:23:23 | 显示全部楼层
多谢二位指点,但小弟水平实在有限,还是不太明白。比如说我在程序中调用:
system("ls 1234.txt");
其中,1234.txt是一个不存在的文件名。执行时shell会返回信息:"No such file or dirctory"
我想要的就是在程序中以字符串的形式获取这个信息,我应该怎么做?请高手别嫌弃我水平低,再指点一下,多谢!
回复 支持 反对

使用道具 举报

发表于 2005-9-4 10:31:30 | 显示全部楼层
简单的可以这样.


int retval = -1;
char cmd[1024];
int xid = 0;

srand(time(0));

xid = rand();
sprintf(cmd,"ls 123.txt 2>/tmp/%d.%d.err",getpid(),xid);

retval = system(cmd);

....
分析那个err文件
回复 支持 反对

使用道具 举报

发表于 2005-9-4 16:19:06 | 显示全部楼层
Post by ma_jingyi
需要在程序中调用shell命令,应该是用这个函数吧?不过当命令执行出错的时候这个函数仅返回一个非零的整型错误代码。请问在程序中用什么方法可以获取这个错误代码所代表的错误信息(String)?

出错的是系统调用,出错后会设置errno全局变量
errno和进程的返回值不是一回事
errno是ls这个进程里的一个变量,其他进程无法获得这个值,所以只能用上面一帖的方法
如果可以获得errno,就方便很多
man strerror

另外system实际上是fork一个进程,然后让它执行sh -c "ls 123"
在wait这个子进程结束
system的返回值就是这个子进程的wait status
从wait status里获得进程返回值要用

  1. int retval;
  2. if (WIFEXITED(status))
  3.     retval = WEXITSTATUS(status);
复制代码
回复 支持 反对

使用道具 举报

发表于 2005-9-4 21:34:12 | 显示全部楼层
if (system ("command") == -1)
{
   fprintf (stderr, "%s", strerror(errno));
}
回复 支持 反对

使用道具 举报

发表于 2005-9-4 22:44:51 | 显示全部楼层
Post by newroot
if (system ("command") == -1)
{
   fprintf (stderr, "%s", strerror(errno));
}

这一段代码有很大问题

首先子进程中发生错误不等于system发生错误,不能导致system返回-1
system只要在fork和wait过程中不发生错误,就算成功

其次man system并无提到system会设置errno
即使设置,这个errno也和No such file or directory无关
errno在支持nptl的glibc里是per thread variable
旧的glibc里也是per process variable
No such file or directory是ls根据ls进程里的errno的值打印出来的
别的进程无法获得这个值
回复 支持 反对

使用道具 举报

发表于 2005-9-5 16:53:40 | 显示全部楼层
int pid = fork();
switch (pid)
{case -1:
   //..error
  case 0:
   execlp("ls","ls","1234.txt",(char *)0);
  default:
  wait(&status)
}

zhllg
int retval;
if (WIFEXITED(status))
    retval = WEXITSTATUS(status);


errno=retval
回复 支持 反对

使用道具 举报

发表于 2005-9-5 22:00:01 | 显示全部楼层
Post by 弥敦路九号

errno=retval

Buddy, are you trying to say that “errno is just the exit status of a process“?

If this is what you mean, then I am so sorry that you are wrong, except that you explicitly save the errno's value after a particular system call/library function you are interested in, and then use the saved value as the exit()'s argument or return the saved value when returning from main().

check man errno

The <errno.h> header file defines the integer variable errno , which is set by system calls and some library functions in the event of an error to  indicate  what  went wrong.

and check man 2 wait

WEXITSTATUS(status)
returns the exit status of the  child.   This  consists  of  the
least  significant  8 bits of the status argument that the child
specified in a call to exit() or _exit() or as the argument  for
a  return  statement  in  main().   This  macro  should  only be
employed if WIFEXITED returned true.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表