Here's a working example of my problem:
def cli = new CliBuilder(usage: 'cli-test -d <argument>')
cli.with {
h(longOpt: 'help', 'usage information')
d(longOpt: 'do-something', required: true, args: 1, 'Do Something' )
}
OptionAccessor options = cli.parse(args)
if(!options) {
return
}
// print usage if -h, --help, or no argument is given
if(options.h || options.arguments().isEmpty()) {
println options.arguments().size()
cli.usage()
return
} else if (options.d) {
println options.d
}
When I execute the script with the following:
groovy cli-test.groovy -d hello
I get this output:
0
usage: cli-test -d <argument>
-d,--do-something <arg> Do Something
-h,--help usage information
The 0 is my println is the arguments length. I can't get any options to work other than h. I'm not sure if I'm doing something wrong.
The reason is that there are no arguments! You've swallowed them all in options.
If you call
groovy cli-test.groovy -d hello foo
then the arguments() list is [foo]
The -d arg is automatically checked for because you made it required, so there's no need to test for it later on.
Not sure why this works this way, but removing:
|| options.arguments().isEmpty()
from the initial if check makes everything work.
Related
How can I perform a try catch in nextflow?
I am currently writing a pipeline where it is possible that the bash command I am executing exits with an exitcode 1 under certain conditions. This brings my pipeline to a grinding halt. I would now like to use a try catch clause to define some alternative behavior in case this happens.
I have tried doing this in groovy fashion which does not seem to work:
process align_kallisto {
publishDir "${params.outdir}/kallisto", mode: 'copy', saveAs:{ filename -> "${name}_abundance.tsv" }
input:
tuple val(name), file(fastq) from fq_kallisto.dump(tag: 'kallisto fq')
file(index) from kallisto_index.collect().dump(tag: 'kallisto index')
output:
file("output/abundance.tsv") into kallisto_quant
// this can throw an exit 1 status
try {
"""
kallisto quant -i ${index} --bias --single --fr-stranded -o output --plaintext \
--fragment-length ${params.frag_length} --sd ${params.frag_deviation} ${fastq}
"""
}
// if this happens catch and do something else
catch (Exception e) {
println("Exception: ${e} for $name")
"""
// execute some alternative command
"""
}
}
Any advise?
I could tell nextflow to just ignore this error and still continue, but I would rather learn how to do a proper try catch.
AFAIK there's no way to handle errors in your process definition using a try/catch block. Rather than trying to catch all of the scenarios that result in an exit status 1, could you better define those conditions and handle them before trying to execute your process? For example, if an empty FASTQ file (or a FASTQ file with an insufficient number of reads as required by your process) was supplied as input and this resulted in an exit status 1, a pre-processing command that filtered out those files could be useful here.
But if it's not possible to better define the condition(s) that your command produces exit status 1 or any non-zero exit status, you can ignore them like you have suggested by appending errorStrategy 'ignore' to your process definition. Below is an example of how you could get the 'success' and 'failed' outputs, so they can be handled appropriately:
nextflow.enable.dsl=2
process test {
errorStrategy 'ignore'
input:
tuple val(name), path(fastq)
output:
tuple val(name), path("output/abundance.tsv")
"""
if [ "${fastq.baseName}" == "empty" ]; then
exit 1
fi
mkdir output
touch output/abundance.tsv
"""
}
workflow {
fastqs = Channel.fromFilePairs( './data/*.fastq', size: 1 )
test(fastqs) \
.join(fastqs, remainder: true) \
.branch { name, abundance, fastq_tuple ->
failed: abundance == null
return tuple( name, *fastq_tuple )
succeeded: true
return tuple( name, abundance )
} \
.set { results }
results.failed.view { "failed: $it" }
results.succeeded.view { "success: $it" }
}
Run with:
mkdir data
touch data/nonempty.fastq
touch data/empty.fastq
nextflow run -ansi-log false test.nf
Results:
N E X T F L O W ~ version 20.10.0
Launching `test.nf` [suspicious_newton] - revision: b883179718
[08/60a99f] Submitted process > test (1)
[42/358d60] Submitted process > test (2)
[08/60a99f] NOTE: Process `test (1)` terminated with an error exit status (1) -- Error is ignored
success: [nonempty, /home/user/working/stackoverflow/66119818/work/42/358d60bd7ac2cd8ed4dd7aef665d62/output/abundance.tsv]
failed: [empty, /home/user/working/stackoverflow/66119818/data/empty.fastq]
I have the Groovy code as below
def retVal = sh(returnStdout: true, script: "curl ${URI}; echo \$?")
println("Return value: ${retVal}") -> it printed 0
if (retVal == "0") {
println("Successfull") -> it doesn't go here
}
why the above condition can't be catched?
First of all, you seem to be using the Jenkins API incorrectly.
If all you need is the exit code of the process, use returnStatus: true:
def retVal = sh(returnStatus: true, script: "curl ${URI}")
if (retVal == 0) {
println 'success'
} else {
println "Something wrong, exit code was $retVal")
}
Now, if you really want the stdout instead, perhaps clean up the String first by calling trim() on it or try to match the String against a regex:
if (retValue ~== /\s*0\s*/) {
println "success"
} else {
println "Something wrong, exit code was '$retVal'")
}
I always put quotes around a value I print to make sure new-lines or whitespaces don't make me waste time with bad values.
I wish to check whether a path given is exists or is a directory in another site server in Perl. My code is as below.
my $destination_path = "<path>";
my $ssh = "usr/bin/ssh";
my $user_id = getpwuid( $< );
my $site = "<site_name>";
my $host = "rsync.$site.com";
if ($ssh $user_id\#$host [-d $destination_path]){
print "Is a directory.\n";
}
else{
print "Is not a directory.\n";
}
I am sure my code is wrong as I modify the code according to bash example I see from another question but I have no clue how to fix it. Thanks for everyone that helps here.
[ is the name of a command, and it must be separated from other words on the command line. So just use more spaces:
$ssh $user\#$host [ -d $destination_path ]
To actually execute this command, you'll want to use the builtin system function. system returns 0 when the command it executes is successful (see the docs at the link)
if (0 == system("$ssh $user\#$host [ -d $destination_path ]")) {
print "Is a directory.\n";
} else {
print "Is not a directory.\n";
}
Accessing the remote file system through SFTP:
use Net::SFTP::Foreign;
$sftp = Net::SFTP::Foreign->new("rsync.$site.com");
if ($sftp->test_d($destination_path)) {
"print $destination_path is a directory!\n";
}
I have an expect command
expect "~]#" { send "virsh list --all\r"}
and the output would be
[root#lht1oneems-unit0 ~]# virsh list --all
Id Name State
----------------------------------------------------
399 lht1duplexvm-0 running
- rhelvm shut off
I want to use $expect_out(buffer) and have an if statement to do something if it finds running and do something else if not.
how can I parse into the result of $expect_out(buffer)?
expect "~]#"
send "virsh list --all\r"
# I assume another prompt follows this
expect "~]#"
if { [regexp {running} $expect_out(buffer)] } {
do-something-for-running-process
} else {
do-something-for-no-running-process
}
You could also do
if {[string first "running" $expect_out(buffer)] >= 0} {
i get this wierd bug.
i have this code, which compares the password in the config file with the given argument:
if(label.equalsIgnoreCase("login")){
if(getConfig().getString("players."+p.getName()+".password") == args[0]){
p.sendMessage("OK!");
} else {
p.sendMessage("NOT OK!");
}
but no matter what, it ouputs "NOT OK!", what am i doing wrong?
ive tried to debug it, to send a message with the given argument and what it sees in the config file.
they were both the same!
You should try
String configValue = config.getString("players."+p.getName()+".password");
if(configValue != null && configValue.equals(args[0]) { // maybe you just need to change the index of args[], depending on if your command looks like /xy <password> or /xy z <password>
p.sendMessage("OK!");
} else {
p.sendMessage("NOT OK!");
}