我必须一个接一个地运行许多程序,每个程序的输出作为下一个程序的输入。
我使用system
和shell脚本尝试使用Perl,但它不理解-parameter
。
这是我的脚本,请帮我解决这个问题。我正在研究Ubuntu。
use strict;
use warnings;
my $filename='';
print "\nEnter file name: ";
$filename=<STDIN>;
system("/usr/local/RepeatMasker/RepeatMasker –species rice $filename");
system("rm $filename.out, $filename.cat, $filename.tbl");
system("/usr/local/blast-2.2.25/bin/blastall –p blastx –i $filename.masked –d ../../database/RGAP-all.pep –o $filename.m.blx");
system("/usr/local/Genomescan/blastx2genoa $filename.m.blx –m /usr/local/Genomescan/BLOSUM62 >$filename.m.genoa");
system("/usr/local/Genomescan/genomescan /usr/local/Genomescan/genomescan-pm/Maize.smat $filename.masked –g $filename.m.genoa –ps $filename.ps >$filename.out");
Print "Done";
运行时,-species
为文件名,不理解-i
或-p
。
答案 0 :(得分:0)
您的system
命令有点难看(请考虑使用multi-argument system),但没有理由说他们不会理解参数&#34;。
但是,我确实在您的代码中看到了其他几个错误:
阅读后你不会chomp $filename
,所以它会以换行符结尾。这意味着,例如"$filename.out"
将评估为类似"whatever\n.out"
的内容,shell会将其解析为两个单独的参数,就像它读取"whatever .out"
一样。
此外,shell命令的参数由空格分隔,而不是逗号。因此,rm
命令中的逗号被解释为要删除的文件名的一部分。 (但是,既然你可能没有任何名为.out,
或.cat,
的文件,那么在修复上面的第一个错误之前,它并没有任何区别。)
(无论如何,你真的不需要拨打rm
.Perl有一个非常好的内置unlink
命令。)
由于您使用system
的单参数形式,因此shell将解析您的命令字符串。这意味着,即使修复了换行符问题,文件名中的任何空格或其他shell元字符也会破坏您的代码。您应该切换到多参数system
(绕过shell)或使用String::ShellQuote。
无论如何,看起来你真的想在Perl中编写一个shell脚本。为什么不把它变成一个诚实的shell脚本?
#!/bin/bash
read -ep "Enter file name: " filename
/usr/local/RepeatMasker/RepeatMasker –species rice "$filename"
rm "$filename.out" "$filename.cat" "$filename.tbl"
/usr/local/blast-2.2.25/bin/blastall –p blastx –i "$filename.masked" –d ../../database/RGAP-all.pep –o "$filename.m.blx"
/usr/local/Genomescan/blastx2genoa "$filename.m.blx" –m /usr/local/Genomescan/BLOSUM62 >"$filename.m.genoa"
/usr/local/Genomescan/genomescan /usr/local/Genomescan/genomescan-pm/Maize.smat "$filename.masked" –g "$filename.m.genoa" –ps "$filename.ps" >"$filename.out"
echo "Done."
这不仅会产生更清晰的代码,而且会自动解决上述大部分问题(
) bash read
命令会自动从输入中删除尾随换行符。
由于shell现在自己进行变量插值,我们可以安全地在文件名周围使用双引号来告诉它将每个文件名视为一个参数,即使$filename
恰好包含空格或其他特殊字符。