如何在C中执行shell脚本?

如何在C中执行shell脚本?,c,shell,C,Shell,我正在尝试创建一个.sh文件,将脚本写入其中,然后使用exec执行它* 到目前为止,我成功地创建了文件并将代码写入其中,但execl没有执行脚本 int main( int argc, char * argv[] ){ char str[] = "#!/bin/bash \n echo 'Hello World!'"; FILE *fp = fopen("script.sh", "w+"); fwrite(str , 1 , sizeof(str) , fp );

我正在尝试创建一个.sh文件,将脚本写入其中,然后使用exec执行它*

到目前为止,我成功地创建了文件并将代码写入其中,但execl没有执行脚本

int main( int argc, char * argv[] ){
    char str[] = "#!/bin/bash \n echo 'Hello World!'";
    FILE *fp = fopen("script.sh", "w+");
    fwrite(str , 1 , sizeof(str) , fp );
    fclose(fp);
    execl ("/usr/bin/chmod", "chmod", "+x", "script.sh", (char *)0);
    execl ("/export/home/redpal/lab4", "script.sh", (char *)0);
    return 0;
}

我是否应该将每个execl放入子进程?

the
excl
函数(与所有函数和系统调用一样)不要返回成功。它只会在失败时返回

所以你的第一个电话:

execl ("/usr/bin/chmod", "chmod", "+x", "script.sh", (char *)0);
很有可能成功。然后您当前的程序消失,您正在运行
/usr/bin/chmod
程序。一旦程序完成(在几毫秒内),您的进程就会退出(并且您的调用shell会给出一个新的提示)

<>而不是使用<代码> /Ur/bin /CHOMD 程序,您应该考虑使用系统调用。< /P> 你程序的其余部分也是错误的。您可能希望
exec
生成的脚本(但是,您需要给出它的整个路径)

您需要了解如何使用、和朋友系统调用运行进程。我们无法解释如何做到这一点(太长了),但您应该阅读本书的几章(可免费下载)

也许你应该考虑在你的实际程序中嵌入一个解释器(所以你的问题看起来像一些)


您可以使用或运行一些命令。。。。可能使用类似于
FILE*cmd=popen(“/bin/sh”,“w”)可能足够了。。。。然后将shell命令写入
cmd
,需要
pclose(cmd)
执行函数(与所有函数和系统调用一样)在成功后不会返回。它只会在失败时返回

所以你的第一个电话:

execl ("/usr/bin/chmod", "chmod", "+x", "script.sh", (char *)0);
很有可能成功。然后您当前的程序消失,您正在运行
/usr/bin/chmod
程序。一旦程序完成(在几毫秒内),您的进程就会退出(并且您的调用shell会给出一个新的提示)

<>而不是使用<代码> /Ur/bin /CHOMD 程序,您应该考虑使用系统调用。< /P> 你程序的其余部分也是错误的。您可能希望
exec
生成的脚本(但是,您需要给出它的整个路径)

您需要了解如何使用、和朋友系统调用运行进程。我们无法解释如何做到这一点(太长了),但您应该阅读本书的几章(可免费下载)

也许你应该考虑在你的实际程序中嵌入一个解释器(所以你的问题看起来像一些)


您可以使用或运行一些命令。。。。可能使用类似于
FILE*cmd=popen(“/bin/sh”,“w”)可能足够了。。。。然后将shell命令写入
cmd
,并且需要
pclose(cmd)

在每个可能失败的命令之后检查错误。 您应该将
sizeof(array)-1
字节写入文件,否则您也将写入终止的零

exec*
syscalls替换进程映像。如果它们成功,您的程序将被刚刚执行的二进制文件所取代。因此,您需要在子进程中执行,或者
exec*
syscall需要是您在程序中执行的最后一件事

在您的情况下,
chmod
执行是完全可以避免的。您可以直接发出
chmod
syscall,也可以确保创建文件,在这种情况下,您可以立即设置权限

我希望如此:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main( int argc, char * argv[] )
{
    unlink("script.sh"); //unchecked -- let it fail if the file's not there
    int fd;
    if(0>(fd = open("script.sh", O_CREAT|O_WRONLY, 0777)))
        { perror("Couldn't create 'script.sh'"); return EXIT_FAILURE; }
    int nr;
    static char const str[] = "#!/bin/bash \n echo 'Hello World!'";
    size_t to_write = sizeof str - 1;
    if( to_write != (nr=write(fd, str, sizeof str - 1)) || 0>close(fd)  )
        { perror("Couldn't write contents"); return EXIT_FAILURE; }
    //writes to the filesystem on linux aren't ever partial unless there's a filesystem error 
    //otherwise you need to account for partial write (which fwrite does for you)

    execl ("./script.sh", "script.sh", (char *)0);
    perror("Couldn't exec './script.sh'");
    return EXIT_FAILURE;
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
unlink(“script.sh”);//未选中--如果文件不存在,则让它失败
int-fd;
如果(0>(fd=open(“script.sh”,O|u CREAT | O|u WRONLY,0777)))
{perror(“无法创建'script.sh'”);返回EXIT_FAILURE;}
国际天然气公司;
静态字符常量str[]=“#!/bin/bash\n echo'Hello World!'”;
写入的大小=str-1的大小;
if(to|u write!=(nr=write(fd,str,sizeof str-1))| | 0>close(fd))
{perror(“无法写入内容”);返回EXIT_FAILURE;}
//在linux上对文件系统的写入永远不会是部分的,除非出现文件系统错误
//否则,您需要考虑部分写入(fwrite为您做的)
execl(“./script.sh”,“script.sh”,“char*)0);
perror(“无法执行“/script.sh”);
返回退出失败;
}

在每个可能失败的命令之后检查错误。 您应该将
sizeof(array)-1
字节写入文件,否则您也将写入终止的零

exec*
syscalls替换进程映像。如果它们成功,您的程序将被刚刚执行的二进制文件所取代。因此,您需要在子进程中执行,或者
exec*
syscall需要是您在程序中执行的最后一件事

在您的情况下,
chmod
执行是完全可以避免的。您可以直接发出
chmod
syscall,也可以确保创建文件,在这种情况下,您可以立即设置权限

我希望如此:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main( int argc, char * argv[] )
{
    unlink("script.sh"); //unchecked -- let it fail if the file's not there
    int fd;
    if(0>(fd = open("script.sh", O_CREAT|O_WRONLY, 0777)))
        { perror("Couldn't create 'script.sh'"); return EXIT_FAILURE; }
    int nr;
    static char const str[] = "#!/bin/bash \n echo 'Hello World!'";
    size_t to_write = sizeof str - 1;
    if( to_write != (nr=write(fd, str, sizeof str - 1)) || 0>close(fd)  )
        { perror("Couldn't write contents"); return EXIT_FAILURE; }
    //writes to the filesystem on linux aren't ever partial unless there's a filesystem error 
    //otherwise you need to account for partial write (which fwrite does for you)

    execl ("./script.sh", "script.sh", (char *)0);
    perror("Couldn't exec './script.sh'");
    return EXIT_FAILURE;
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
unlink(“script.sh”);//未选中--如果文件不存在,则让它失败
int-fd;
如果(0>(fd=open(“script.sh”,O|u CREAT | O|u WRONLY,0777)))
{perror(“无法创建'script.sh'”);返回EXIT_FAILURE;}
国际天然气公司;
静态字符常量str[]=“#!/bin/bash\n echo'Hello World!'”;
写入的大小=str-1的大小;
if(to|u write!=(nr=write(fd,str,sizeof str-1))| | 0>close(fd))
{perror(“无法写入内容”);返回EXIT_FAILURE;}
//在linux上对文件系统的写入永远不会是部分的,除非出现文件系统错误
//否则,您需要考虑部分写入(fwrite为您做的)
execl(“./script.sh”,“script.sh”,“char*)0);
perror(“无法执行“/script.sh”);