使用echo和system在C中运行软件

时间:2014-06-02 18:58:12

标签: c shell blast

我正在尝试运行一个名为BLASTP的生物程序,该程序接受两个字符串(代码中的fasta_GWIDD和fasta_UNIPROT)并对它们进行比较。我遇到的问题是在代码中使用echo / system。任何人都可以建议我错过了什么?

    for(i=0;i<index1;i++)
    {
        sprintf(fasta_GWIDD,">%s\\n%s\n",fasta_name1[i],fasta_seq1[i]);
        setenv("GwiddVar", fasta_GWIDD, 1) ;
        sprintf(fasta_UNIPROT,">%s\\n%s\n",fasta_name2[i],fasta_seq2[i]);
        setenv("UniprotVar", fasta_UNIPROT, 1) ;
        system("blastp -query <(echo -e $GwiddVar) -subject<(echo -e $UniprotVar)");
    }

错误是:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `blastp -query <(echo -e $GwiddVar) -subject<(echo -e $UniprotVar)'

2 个答案:

答案 0 :(得分:4)

似乎shell不理解

<(echo -e $GwiddVar)

语法。请注意system命令可能使用与您习惯的shell不同的shell(比如csh而不是bash,依此类推)。它是你的操作系统配置文件和配置文件中某些地方的所有内容,但我不知道你在那里有什么。

顺便说一下。我认为你应该能够通过以下任何一种来检查system()命令正在使用哪个shell:

system("echo $SHELL")  // should simply write the path to current shell
system("ps -aux")      // look at it and find what is the parent of the PS

考虑到在某些shell上这是正确的:

blastp -query <(echo -e $GwiddVar) -subject<(echo -e $UniprotVar)

上面引用的语法显然只是为了将变量作为intput传递。我觉得你做得太过分了。您正在使用echo -e $GwiddVar来打印和捕获数据,这些数据已经存在于可用的可用数据库中。你尝试过这么简单的事情:

blastp -query $GwiddVar -subject $UniprotVar

我不知道您尝试使用哪个shell,但考虑到echo得到了它的数据,那么它应该完全相同。

如果你担心空格,那么各种shell通常允许你使用引号:

blastp -query "$GwiddVar" -subject "$UniprotVar"

当然这取决于shell。如果你的程序使用了不喜欢引号的shell,那么你必须适应它。不是你的shell,而是system()使用的shell。

另一件事是使用system非常粗糙。当你的参数难以正确转义时,你应该使用其他函数like execve,它们能够获取一组真正的原始直接字符串,并将它们作为ARGV直接传递给进程。使用这些,您不需要(也不应该)添加任何引号或转义要传递的字符串中的任何空格。

sprintf(fasta_GWIDD,">%s\\n%s\n",fasta_name1[i],fasta_seq1[i]);
sprintf(fasta_UNIPROT,">%s\\n%s\n",fasta_name2[i],fasta_seq2[i]);

char** args = .....; // allocate an array of char*[5], malloc, or whatever
args[0] = "blastp";
args[1] = "-query";
args[2] = fasta_GWIDD;
args[3] = "-subject";
args[4] = fasta_UNIPROT;

int errcode = execve(4, args, null);
if( errcode ) ... // check the error (if any) and react

然而!请注意,execve来自exec系列,因此它取代了您当前的进程。这就是为什么我只写一个草图而不显示整个准备运行的代码。你可能需要在它之前fork(),然后等待外循环中的孩子。

所以,我首先检查shell和语法;)

答案 1 :(得分:0)

来自man 3 system

DESCRIPTION
    system()  executes a command specified in command by calling /bin/sh -c
    command, and returns after the command has been completed.

在许多系统上,/bin/sh不是bash,即使是bash,它也是bash的不同配置(/bin/sh通常在调用时会有不同的操作作为bash)。因此,您要将bash语法传递给一个不是bash的shell,或者不允许完整的-system - isms ...而且,那里有&#39 ; system()之后的空格也可能让人感到困惑......而且,我并不完全确定环境变量是否在{{1}}字符串中展开......