腳本
腳本是字符串聲明,它定義了由過程執行到執行任務的命令。
一個進程僅包含一個腳本塊,并且當該進程包含輸入和輸出聲明時,它必須是最后一個語句。
輸入的字符串在主機系統中作為Bash腳本執行。它可以是通常在終端 shell 程序或通用Bash腳本中使用的任何命令,腳本或它們的組合。
可以在腳本語句中使用的命令的唯一限制是目標執行系統中這些程序的可用性。
腳本可以是簡單字符串或多行字符串,例如:
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
變量被替換為管道腳本中已經定義的實際值。
需要在腳本中訪問系統環境變量時,有兩個選擇。
- 首選就像使用單引號字符串定義腳本塊一樣容易。例如:
process printPath {
'''
echo The path is: $PATH
'''
}
該解決方案的缺點是,您將無法在腳本中訪問在管道腳本上下文中定義的變量。
- 要解決此問題,請使用雙引號字符串定義腳本,并通過在系統環境變量前添加反斜杠字符來對其進行轉義
\
,如以下示例所示:
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
必須在管道腳本定義變量。 在執行腳本之前,Nextflow用實際值替換它。
$DB
變量必須存在于腳本執行環境中,并且Bash解釋器將其替換為實際值。
另外,您可以使用Shell塊定義,該定義允許腳本包含Bash和Nextflow變量,而不必轉義第一個。
使用其他語言的腳本
默認情況下,Nextflow流程腳本為Bash腳本,但您不僅限于此。
您可以使用自己喜歡的腳本語言(例如Perl,Python,Ruby,R等),甚至可以將它們混合在同一管道中。
管道可以由執行不同的任務的進程組成。使用Nextflow,您可以選擇更適合指定進程執行的任務的腳本語言。
例如,對于某些進程,R可能比Perl有用,在其他進程中,您可能需要使用Python,因為它提供了對庫或API等的更好訪問。
要使用Bash以外的腳本,只需使用相應的shebang聲明啟動流程腳本 。例如:
process perlStuff {
"""
#!/usr/bin/perl
print 'Hi there!' . '\n';
"""
}
process pyStuff {
"""
#!/usr/bin/python
x = 'Hello'
y = 'world!'
print "%s - %s" % (x,y)
"""
}
由于解釋器二進制文件的實際位置可以在各個平臺上變化,因此為了使腳本更易于移植,在聲明時,使用#!/usr/bin/env perl
。這是使用env
shell命令,后跟解釋器的名稱,而不是其絕對路徑。
根據條件執行不同腳本
復雜的過程腳本可能需要評估對輸入參數的條件,或使用傳統的流量控制語句(即if
,switch
等),根據當前輸入的配置,以執行特定的腳本命令。
流程腳本可以通過簡單地在腳本塊前面加上關鍵字來包含條件語句script:
。
然后,解釋器將評估以下所有語句作為必須返回要執行的腳本字符串的代碼塊。例如:
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}"
}
在上面的示例中,該過程將根據mode
參數的值執行腳本片段。默認情況下它將執行tcoffee
命令,將mode
變量更改為mafft
or clustalo
值,其他分支將被執行。
模板
可以使用模板文件將流程腳本外部化,該模板文件可以在不同的流程之間重復使用,并且可以通過整體管道執行獨立地進行測試。
模板只是Nextflow可以通過使用如下template
功能執行的shell腳本文件:
process template_example {
input:
val STR from 'this', 'that'
script:
template 'my_script.sh'
}
Nextflow my_script.sh
在目錄templates
中尋找模板文件,該目錄必須存在于Nextflow腳本文件所在的文件夾中(可以使用絕對模板路徑提供任何其他位置)。
模板腳本可以包含基礎系統可以執行的任何代碼。例如:
#!/bin/bash
echo "process started at `date`"
echo $STR
:
echo "process completed"
注意$
,當腳本作為Nextflow模板運行時,$
被解釋為Nextflow變量占位符,而單獨運行時,被評估為Bash變量。這對于自主地(即獨立于Nextflow執行)測試腳本非常有用。
您只需為腳本中存在的每個Nextflow變量提供一個Bash環境變量。例如,可以在shell終端中輸入以下命令來執行上述腳本:STR='foo' bash templates/my_script.sh
shell
該shell
塊是一個字符串語句,用于定義由進程執行以執行其任務的shell命令。它是Script定義的替代方案,但有重要區別,它使用感嘆號!
字符作為Nextflow變量的變量占位符,代替了通常的美元字符。
這樣,可以在同一段代碼中同時使用Nextflow和Bash變量,而不必逃避后者,并使流程腳本更具可讀性和易于維護。例如:
process myTask {
input:
val str from 'Hello', 'Hola', 'Bonjour'
shell:
'''
echo User $USER says !{str}
'''
}
在上面的瑣碎示例中,$USER
變量由Bash解釋器管理,而!{str}
作為由Nextflow管理的流程輸入變量進行處理。
注意
- Shell腳本定義要求使用單引號
'
分隔的字符串。使用雙引號"
分隔的字符串時,美元變量照常解釋為Nextflow變量。請參閱字符串插值。 - 感嘆號前綴變量始終需要用大括號括起來,即被忽略
!{str}
時!str
是有效變量。 - Shell腳本支持使用文件模板機制。相同的規則適用于腳本模板中定義的變量。
本機執行
Nextflow進程可以執行除系統腳本以外的本機代碼,如前幾段所示。
這意味著,您無需指定要作為字符串腳本執行的process命令,而是可以提供一種或多種語言語句來定義它,就像在其余管道腳本中一樣。只需使用exec:
關鍵字啟動腳本定義塊,例如:
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