在很多脚本中,我们常看到这样的写法, 一般称为shebang 语句,比如
- #!/bin/bash 用于定义和执行一个bash 脚本
- #!/usr/bin/perl 用于定义和执行一个perl 脚本
- #!/usr/bin/python 用于定义和执行一个python 脚本
- #!/usr/bin/Rscript 用于定义和执行一个R 脚本
这样写的好处是,我们每一个放到了环境变量 ( 关于环境变量,你可能需要看下 PATH和path,傻傻分不清)且有可执行权限的脚本都可以直接调用运行。比如有一个脚本名字叫do_all_analysis.py 在~/bin 目录下,你有下面几种运行方式:
- do_all_analysis.py
- ~/bin/do_all_analysis.py
- python ~/bin/do_all_analysis.py
第一种无疑是最简单、通用的方式, 但需要程序满足三个条件:1. 有shebang 语句;2. 有可执行权限;3. 该脚本放在了环境变量包含的一个路径下。
当然上面的写法还存在一些问题,尤其是我们在用了 conda 环境或自己自定义位置安装了不同语言的解释器程序后,比如你把R 安装在了自己家目录下,例如~/R/,相应的 Rscript 的路径也要跟着变(#!~/R/bin/Rscript),这样脚本给别人用时就不太方便了,可能就好直接报错了,找不到Rscript。
最近运行GeneMark软件进行基因预测时,发现里面的 perl 程序找不到一些依赖模块,看了下,perl 程序中的 shebang 语句是这么写的#!/usr/bin/perl,而我把相应的模块都通过conda 安装在了一个环境下, 两个路径不一致,所以找不到。解决方法有 3 个:
- 设置 PERL5LIB环境变量,把 conda 中 perl 模块的路径加进去。
- 如果只是一台电脑用,没问题;
- 但迁移时就会麻烦些,每台电脑都需要设置。
- 用根目录下的 perl 重装一遍模块。缺点同 1.
- 修改shebang 语句为#!/usr/bin/env perl,让程序运行时自己去找当前环境变量中的perl 解释器 ( 我激活了 conda 环境,肯定用的是 conda 里面的解释器),再根据解释器去匹配模块位置,就没问题了。
也是为了脚本的可移植性,建议上述shebang 语句都用下面的写法:
- #!/bin/env bash 用于定义和执行一个bash 脚本
- #!/usr/bin/env perl 用于定义和执行一个perl 脚本
- #!/usr/bin/env python 用于定义和执行一个python 脚本
- #!/usr/bin/env Rscript 用于定义和执行一个R 脚本
这样程序运行时会根据$PATH 中指定的解释器,做出正确的选择。
https://pixabay.com/photos/mongolian-girl-traditional-clothes-7336271/