我在运行某个流程的主程序脚本的时候,经常会出现几个问题,让人很头疼。经过版主的帮助,终于理解了问题所在。在此,将我遇到的问题和解决方式分享出来,同时也是对版主耐心讲解的一种致敬。
我运行的主程序miRDeep2.pl,它会调用各种程序,比如sanity_check_mature_ref.pl,在调用的时候,它是直接运行
sanity_check_mature_ref.pl 05.mirdeep2_c/mature.hsa.fa (1)
而不是:
perl /path/mirdeep2_0_0_7/sanity_check_mature_ref.pl 05.mirdeep2_c/mature.hsa.fa (2)
也不是:
/path/perl/5.16.3/install/bin/perl /path/mirdeep2_0_0_7/sanity_check_mature_ref.pl 05.mirdeep2_c/mature.hsa.fa (3)
1. perl解释器的选择问题
第一种运行的时候:sanity_check_mature_ref.pl 05.mirdeep2_c/mature.hsa.fa (1)
会按sanity_check_mature_ref.pl脚本第一行的/usr/bin/perl 来找perl解释器,也就是说,用/usr/bin/perl来运行脚本。
而且,加入你的目录中有多个“sanity_check_mature_ref.pl”脚本,最终运行的,将是在你的PATH中最先找到的那个“sanity_check_mature_ref.pl”。
第二种运行的时候:perl /path/mirdeep2_0_0_7/sanity_check_mature_ref.pl 05.mirdeep2_c/mature.hsa.fa (2)
会用你PATH中最先找到的那个perl解释器来运行脚本。
第三种:/path/perl/5.16.3/install/bin/perl /path/mirdeep2_0_0_7/sanity_check_mature_ref.pl 05.mirdeep2_c/mature.hsa.fa (3)
会用/path/perl/5.16.3/install/bin/perl来运行脚本。
用二、三种方式运行的时候:
因为 脚本“sanity_check_mature_ref.pl” 第一行(shebang line):#!/解释器/的/路径 是 #开头的,
那一行就会被作为注释而忽略。
2. 模块调用问题:
perl程序在运行过程中长调用其他模块。一般地说,perl都是在@INC中挨个地搜索要调用的模块的,@INC可以在“.bashrc”文件中的export PERL5LIB="/PATH/VEP/ensembl-tools-release-80:$PERL5LIB"来设置。
因此,上面三种运行方式,都能在@INC中搜索所需要的模块。但是有的模块可能跟perl解释器绑定在一起的。这类模块有可能是C语言实现的,需要编译。这种模块,你要调用,就必须保证你所用的perl解释器安装了该模块,否则无法调用,也无法用@INC来设置。
以下是群主当时的解释:
=========================================================================================
你执行一个程序的时候, 如果是脚本文件,
脚本文件会有第一行 #!/解释器/的/路径
这个叫做 shebang line, 这一行的作用就是告诉内核, 用哪个解释器来执行这个脚本文件。
而当你在命令行用 /完整路径/的/perl 脚本.pl
这个语法执行的时候, 因为 #!/解释器/的/路径 是 #开头的,
那 那一行就会被作为注释而忽略。
当时当你用 脚本.pl 执行的时候,
内核会在文件的头几行找 shebang line,
=========================================================================================