Why is this docopt string not working either with or without optional args? - docopt

Here is the complete docopt string I used:
foo.
Usage:
foo [options] <file> -o <output>
foo --help | --version
Options:
-h, --help print this help message.
--target <target> target.
--version print the version.
According to the official parser, either foo a -o b or foo --target abc a -o b is not correctly parsed. What could be possible reasons for this case? Any help would be appreciated.

I'm not entirely sure about the allowed combinations of options for your script, but here's something that should be close.
Just for fun, I wrote a script that has similar options to yours to test this out with the latest docopts.
I found it simplest to write just [options] in the main Usage section, and have all the options below as alternatives, with no specific combinations required.
I'm on macOS so I'm using bash 3.2 (with patched docopts.sh to fix some Mac issues). You can avoid some of the code in this script if you're on bash 4.x - see the commented-out section with --auto option and docopt_print_ARGS function. Currently you would need bash 4.x to avoid patching docopts.sh.
#!/bin/bash
#
# foo.
#
# Usage:
# foo [options] <file>
# foo --help | --version
#
# Options:
# -t, --target <target> target.
# -o, --output <output> output.
# -h, --help print this help message.
# --version print the version.
#
# bash 3.2 (patched docopts.sh) - include set -x to see the args easily
source docopts.sh
usage=$(docopt_get_help_string "$0")
set -x
eval "$(docopts -G ARGS -V "$VERSION" -h "$usage" : "$#")"
# On bash 4.x, replace preceding section with this, or use -A instead of -G above
# source docopts.sh --auto "$#"
# docopt_print_ARGS
This parses the Usage section OK and processes command lines such as:
foo --target a -o b file1
foo --target a --output b file1
foo --target a file1
Partial output with set -x to show args processed correctly:
$ ./foo --target a file1 --output b
...
++ ARGS_target=a
++ ARGS_output=b
++ ARGS_file=file1
++ ARGS_help=false
++ ARGS_version=false

Thanks for #RichVel's efforts. Yesterday I finally found out the underlying (stupid) cause for this problem.
In the official online parser the first part, i.e. foo shouldn't be used. --target abc a -o b works fine in the online example.
Regarding my question, the bug actually comes from that docopt.rs stores --target abc in flag_target instead of arg_target.

Related

Samtools/hpc/truncated file

I have tried to submit the script below to HPC
#!/bin/bash
#PBS -N bwa_mem_tumor
#PBS -q batch
#PBS -l walltime=02:00:00
#PBS -l nodes=2:ppn=2
#PBS -j oe
sample=x
ref=absolute/path/GRCh38.p13.genome.fa
fwd=absolutepath/forward_read.fq.gz
rev=absolutepath/reverse_read.fq.gz
module load bio/samtools/1.9
bwa mem $ref $fwd $rev > $sample.tumor.sam && samtools view -S $sample.tumor.sam -b > $sample.tumor.bam && samtools sort $sample.tumor.bam > $sample.tumor.sorted.bam
However as an output I can get only the $sample.tumor.sam and log file says that
Lmod has detected the following error: The following module(s) are unknown:
"bio/samtools/1.9"
Please check the spelling or version number. Also try "module spider ..."
It is also possible your cache file is out-of-date; it may help to try:
$ module --ignore-cache load "bio/samtools/1.9"
Also make sure that all modulefiles written in TCL start with the string
#%Module
However when I input modeles avail it shows that bio/samtools/1.9 is on the list.
Also when i use the option module --ignore-cache load "bio/samtools/1.9"
the result is the same
If i try to continue working with the sam file and input manually the command line
samtools view -b RS0107.tumor.sam > RS0107.tumor.bam
it shows
[W::sam_read1] Parse error at line 200943
[main_samview] truncated file.
What's possibly wrong with the samtools module ir we with the script?

Why "-n" is commonly used for dry-run?

Well known commands like make, rsync, and, git use -n option for dry-run.
What does -n stand for in this context?
My guess is that it's because dry-run contains the letter n and because d and r are already used:
$ make --help | grep '^ *-[dr]'
-d Print lots of debugging information.
-r, --no-builtin-rules Disable the built-in implicit rules.
$ rsync --help | grep '^ *-[dr]'
-r, --recursive recurse into directories
-d, --dirs transfer directories without recursing

How to implement dynamic tab completion of options in Fish shell?

I want to implement dynamic tab completion of options to a Fish command. This is easy for the -a switch, but I can't figure out how to do it for the -l switch.
Consider the following lines:
$ complete -c foo -a '(echo bar\nbaz\nbiz)' -f
$ complete -c foo -l '(echo bar\nbaz\nbiz)' -f
The behavior of my shell is then as follows:
$ foo b<tab>
bar baz biz
$ foo --<tab>
foo --\(echo\ bar\\nbaz\\nbiz\)
Instead I'd like it to suggest three options --bar, --baz and --biz. Is this possible?
edit: Now I understand better. You can do this by just making your "arguments" start with dashes. Here's an example that uses a function for clarity:
function get_foo_completions
echo --bar
echo --baz
echo --biz
set prev_arg (commandline -pco)[-1]
test "$prev_arg" = print
and echo --conditional
end
complete -c foo -a '(get_foo_completions)' -f
The --conditional argument will only be printed if the previous argument is print which illustrates that these can be dynamic.
To my knowledge this isn't yet possible. Options are declarative, and only arguments to those options may be dynamic.
If you give more details about your use case I might be able to suggest other approaches.

Inconsistent External Command Output

The terminal transcript speaks for itself:
iMac:~$ echo -n a | md5
0cc175b9c0f1b6a831c399e269772661
iMac:~$ perl -e 'system "echo -n a | md5"'
c3392e9373ccca33629d82b17699420f
Note that the MD5 hash of a is 0cc175b9c0f1b6a831c399e269772661, the first
result. Why does it turns out to be different when the same command is called
by perl?
By the way, perl is perl 5, version 12, subversion 4 (v5.12.4) built for darwin-thread-multi-2level. And the system: Mac OS 10.8, Darwin 12.0
When in the /bin/sh shell on mac, echo -n doesn't not print out the newline like it does in /bin/bash. You can see this if you drop into /bin/sh and run echo -n a, your output should look like this:
sh-3.2$ echo -n a
-n a
so you're literally getting -n a instead of the desired a. As perl system runs /bin/sh to evaluate your command, -n a is being passed into md5 instead of your desired a
The specific question has already been answered, but I want to point out that od is useful to help understand exactly what any command outputs or file contains. This is useful especially to show otherwise non-printing characters.
$ echo -n a | od -tc
0000000 a
0000001
$ perl -e 'system "echo -n a | od -tc";'
0000000 - n a \n
0000005

Check if program is in path

Can sh itself check if a program exists or is in path?
I.e., not with the help of the "which" program.
I don't believe sh can directly. But perhaps something like:
which() {
save_IFS=$IFS
IFS=:
for d in $PATH; do
test -x $d/$1 && echo $d/$1
done
IFS=$save_IFS
}
and here's a nice variation that uses a subshell so that restoring IFS is not necessary:
which() (
IFS=:
for d in $PATH; do
test -x $d/$1 && echo $d/$1
done
)
Also, (in bash) if the command has been executed in the past and bash has already done the PATH search, you can see what it found with hash -t.
bash-3.2$ hash -t which
bash: hash: which: not found
bash-3.2$ which foo
bash-3.2$ hash -t which
/usr/bin/which
The utility command -v $CMD is apparently a portable option (in the sense of being part of POSIX); see also the very similar (though bash-specific) question, in particular this answer.