腳本
腳本是字符串聲明,它定義了由過程執(zhí)行到執(zhí)行任務(wù)的命令。
一個進(jìn)程僅包含一個腳本塊,并且當(dāng)該進(jìn)程包含輸入和輸出聲明時最盅,它必須是最后一個語句。
輸入的字符串在主機系統(tǒng)中作為Bash腳本執(zhí)行起惕。它可以是通常在終端 shell 程序或通用Bash腳本中使用的任何命令涡贱,腳本或它們的組合。
可以在腳本語句中使用的命令的唯一限制是目標(biāo)執(zhí)行系統(tǒng)中這些程序的可用性惹想。
腳本可以是簡單字符串或多行字符串问词,例如:
process doMoreThings {
"""
blastp -db $db -query query.fa -outfmt 6 > blast_result
cat blast_result | head -n 10 | cut -f 2 > top_hits
blastdbcmd -db $db -entry_batch top_hits > sequences
"""
}
可以使用單引號或雙引號定義字符串,并使用三個單引號或三個雙引號字符定義多行字符串嘀粱。
需要注意激挪,在Bash中,以字符分隔的字符串"
支持變量替換锋叨,而以字符分隔的字符串'
則不支持灌灾。
在上面的代碼片段中,$db
變量被替換為管道腳本中已經(jīng)定義的實際值悲柱。
需要在腳本中訪問系統(tǒng)環(huán)境變量時,有兩個選擇些己。
- 首選就像使用單引號字符串定義腳本塊一樣容易豌鸡。例如:
process printPath {
'''
echo The path is: $PATH
'''
}
該解決方案的缺點是,您將無法在腳本中訪問在管道腳本上下文中定義的變量段标。
- 要解決此問題涯冠,請使用雙引號字符串定義腳本,并通過在系統(tǒng)環(huán)境變量前添加反斜杠字符來對其進(jìn)行轉(zhuǎn)義
\
逼庞,如以下示例所示:
process doOtherThings {
"""
blastp -db \$DB -query query.fa -outfmt 6 > blast_result
cat blast_result | head -n $MAX | cut -f 2 > top_hits
blastdbcmd -db \$DB -entry_batch top_hits > sequences
"""
}
在此示例中蛇更,$MAX
必須在管道腳本定義變量。 在執(zhí)行腳本之前赛糟,Nextflow用實際值替換它派任。
$DB
變量必須存在于腳本執(zhí)行環(huán)境中,并且Bash解釋器將其替換為實際值璧南。
另外掌逛,您可以使用Shell塊定義,該定義允許腳本包含Bash和Nextflow變量司倚,而不必轉(zhuǎn)義第一個豆混。
使用其他語言的腳本
默認(rèn)情況下篓像,Nextflow流程腳本為Bash腳本,但您不僅限于此皿伺。
您可以使用自己喜歡的腳本語言(例如Perl员辩,Python,Ruby鸵鸥,R等)奠滑,甚至可以將它們混合在同一管道中。
管道可以由執(zhí)行不同的任務(wù)的進(jìn)程組成脂男。使用Nextflow养叛,您可以選擇更適合指定進(jìn)程執(zhí)行的任務(wù)的腳本語言。
例如宰翅,對于某些進(jìn)程弃甥,R可能比Perl有用,在其他進(jìn)程中汁讼,您可能需要使用Python淆攻,因為它提供了對庫或API等的更好訪問。
要使用Bash以外的腳本嘿架,只需使用相應(yīng)的shebang聲明啟動流程腳本 瓶珊。例如:
process perlStuff {
"""
#!/usr/bin/perl
print 'Hi there!' . '\n';
"""
}
process pyStuff {
"""
#!/usr/bin/python
x = 'Hello'
y = 'world!'
print "%s - %s" % (x,y)
"""
}
由于解釋器二進(jìn)制文件的實際位置可以在各個平臺上變化,因此為了使腳本更易于移植耸彪,在聲明時伞芹,使用#!/usr/bin/env perl
。這是使用env
shell命令蝉娜,后跟解釋器的名稱唱较,而不是其絕對路徑。
根據(jù)條件執(zhí)行不同腳本
復(fù)雜的過程腳本可能需要評估對輸入?yún)?shù)的條件召川,或使用傳統(tǒng)的流量控制語句(即if
南缓,switch
等),根據(jù)當(dāng)前輸入的配置荧呐,以執(zhí)行特定的腳本命令汉形。
流程腳本可以通過簡單地在腳本塊前面加上關(guān)鍵字來包含條件語句script:
。
然后倍阐,解釋器將評估以下所有語句作為必須返回要執(zhí)行的腳本字符串的代碼塊概疆。例如:
seq_to_align = ...
mode = 'tcoffee'
process align {
input:
file seq_to_aln from sequences
script:
if( mode == 'tcoffee' )
"""
t_coffee -in $seq_to_aln > out_file
"""
else if( mode == 'mafft' )
"""
mafft --anysymbol --parttree --quiet $seq_to_aln > out_file
"""
else if( mode == 'clustalo' )
"""
clustalo -i $seq_to_aln -o out_file
"""
else
error "Invalid alignment mode: ${mode}"
}
在上面的示例中,該過程將根據(jù)mode
參數(shù)的值執(zhí)行腳本片段峰搪。默認(rèn)情況下它將執(zhí)行tcoffee
命令届案,將mode
變量更改為mafft
or clustalo
值,其他分支將被執(zhí)行罢艾。
模板
可以使用模板文件將流程腳本外部化楣颠,該模板文件可以在不同的流程之間重復(fù)使用尽纽,并且可以通過整體管道執(zhí)行獨立地進(jìn)行測試。
模板只是Nextflow可以通過使用如下template
功能執(zhí)行的shell腳本文件:
process template_example {
input:
val STR from 'this', 'that'
script:
template 'my_script.sh'
}
Nextflow my_script.sh
在目錄templates
中尋找模板文件童漩,該目錄必須存在于Nextflow腳本文件所在的文件夾中(可以使用絕對模板路徑提供任何其他位置)弄贿。
模板腳本可以包含基礎(chǔ)系統(tǒng)可以執(zhí)行的任何代碼。例如:
#!/bin/bash
echo "process started at `date`"
echo $STR
:
echo "process completed"
注意$
矫膨,當(dāng)腳本作為Nextflow模板運行時差凹,$
被解釋為Nextflow變量占位符,而單獨運行時侧馅,被評估為Bash變量危尿。這對于自主地(即獨立于Nextflow執(zhí)行)測試腳本非常有用。
您只需為腳本中存在的每個Nextflow變量提供一個Bash環(huán)境變量馁痴。例如谊娇,可以在shell終端中輸入以下命令來執(zhí)行上述腳本:STR='foo' bash templates/my_script.sh
shell
該shell
塊是一個字符串語句,用于定義由進(jìn)程執(zhí)行以執(zhí)行其任務(wù)的shell命令罗晕。它是Script定義的替代方案济欢,但有重要區(qū)別,它使用感嘆號!
字符作為Nextflow變量的變量占位符小渊,代替了通常的美元字符法褥。
這樣,可以在同一段代碼中同時使用Nextflow和Bash變量酬屉,而不必逃避后者半等,并使流程腳本更具可讀性和易于維護。例如:
process myTask {
input:
val str from 'Hello', 'Hola', 'Bonjour'
shell:
'''
echo User $USER says !{str}
'''
}
在上面的瑣碎示例中呐萨,$USER
變量由Bash解釋器管理杀饵,而!{str}
作為由Nextflow管理的流程輸入變量進(jìn)行處理。
注意
- Shell腳本定義要求使用單引號
'
分隔的字符串垛吗。使用雙引號"
分隔的字符串時,美元變量照常解釋為Nextflow變量烁登。請參閱字符串插值怯屉。 - 感嘆號前綴變量始終需要用大括號括起來,即被忽略
!{str}
時!str
是有效變量饵沧。 - Shell腳本支持使用文件模板機制锨络。相同的規(guī)則適用于腳本模板中定義的變量。
本機執(zhí)行
Nextflow進(jìn)程可以執(zhí)行除系統(tǒng)腳本以外的本機代碼狼牺,如前幾段所示羡儿。
這意味著,您無需指定要作為字符串腳本執(zhí)行的process命令是钥,而是可以提供一種或多種語言語句來定義它掠归,就像在其余管道腳本中一樣缅叠。只需使用exec:
關(guān)鍵字啟動腳本定義塊,例如:
x = Channel.from( 'a', 'b', 'c')
process simpleSum {
input:
val x
exec:
println "Hello Mr. $x"
}
將顯示:
Hello Mr. b
Hello Mr. a
Hello Mr. c