annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/opt/bbmap-39.01-1/bbduk.sh @ 69:33d812a61356

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
rev   line source
jpayne@69 1 #!/bin/bash
jpayne@69 2
jpayne@69 3 usage(){
jpayne@69 4 echo "
jpayne@69 5 Written by Brian Bushnell
jpayne@69 6 Last modified July 28, 2022
jpayne@69 7
jpayne@69 8 Description: Compares reads to the kmers in a reference dataset, optionally
jpayne@69 9 allowing an edit distance. Splits the reads into two outputs - those that
jpayne@69 10 match the reference, and those that don't. Can also trim (remove) the matching
jpayne@69 11 parts of the reads rather than binning the reads.
jpayne@69 12 Please read bbmap/docs/guides/BBDukGuide.txt for more information.
jpayne@69 13
jpayne@69 14 Usage: bbduk.sh in=<input file> out=<output file> ref=<contaminant files>
jpayne@69 15
jpayne@69 16 Input may be stdin or a fasta or fastq file, compressed or uncompressed.
jpayne@69 17 If you pipe via stdin/stdout, please include the file type; e.g. for gzipped
jpayne@69 18 fasta input, set in=stdin.fa.gz
jpayne@69 19
jpayne@69 20 Input parameters:
jpayne@69 21 in=<file> Main input. in=stdin.fq will pipe from stdin.
jpayne@69 22 in2=<file> Input for 2nd read of pairs in a different file.
jpayne@69 23 ref=<file,file> Comma-delimited list of reference files.
jpayne@69 24 In addition to filenames, you may also use the keywords:
jpayne@69 25 adapters, artifacts, phix, lambda, pjet, mtst, kapa
jpayne@69 26 literal=<seq,seq> Comma-delimited list of literal reference sequences.
jpayne@69 27 touppercase=f (tuc) Change all bases upper-case.
jpayne@69 28 interleaved=auto (int) t/f overrides interleaved autodetection.
jpayne@69 29 qin=auto Input quality offset: 33 (Sanger), 64, or auto.
jpayne@69 30 reads=-1 If positive, quit after processing X reads or pairs.
jpayne@69 31 copyundefined=f (cu) Process non-AGCT IUPAC reference bases by making all
jpayne@69 32 possible unambiguous copies. Intended for short motifs
jpayne@69 33 or adapter barcodes, as time/memory use is exponential.
jpayne@69 34 samplerate=1 Set lower to only process a fraction of input reads.
jpayne@69 35 samref=<file> Optional reference fasta for processing sam files.
jpayne@69 36
jpayne@69 37 Output parameters:
jpayne@69 38 out=<file> (outnonmatch) Write reads here that do not contain
jpayne@69 39 kmers matching the database. 'out=stdout.fq' will pipe
jpayne@69 40 to standard out.
jpayne@69 41 out2=<file> (outnonmatch2) Use this to write 2nd read of pairs to a
jpayne@69 42 different file.
jpayne@69 43 outm=<file> (outmatch) Write reads here that fail filters. In default
jpayne@69 44 kfilter mode, this means any read with a matching kmer.
jpayne@69 45 In any mode, it also includes reads that fail filters such
jpayne@69 46 as minlength, mingc, maxgc, entropy, etc. In other words,
jpayne@69 47 it includes all reads that do not go to 'out'.
jpayne@69 48 outm2=<file> (outmatch2) Use this to write 2nd read of pairs to a
jpayne@69 49 different file.
jpayne@69 50 outs=<file> (outsingle) Use this to write singleton reads whose mate
jpayne@69 51 was trimmed shorter than minlen.
jpayne@69 52 stats=<file> Write statistics about which contamininants were detected.
jpayne@69 53 refstats=<file> Write statistics on a per-reference-file basis.
jpayne@69 54 rpkm=<file> Write RPKM for each reference sequence (for RNA-seq).
jpayne@69 55 dump=<file> Dump kmer tables to a file, in fasta format.
jpayne@69 56 duk=<file> Write statistics in duk's format. *DEPRECATED*
jpayne@69 57 nzo=t Only write statistics about ref sequences with nonzero hits.
jpayne@69 58 overwrite=t (ow) Grant permission to overwrite files.
jpayne@69 59 showspeed=t (ss) 'f' suppresses display of processing speed.
jpayne@69 60 ziplevel=2 (zl) Compression level; 1 (min) through 9 (max).
jpayne@69 61 fastawrap=70 Length of lines in fasta output.
jpayne@69 62 qout=auto Output quality offset: 33 (Sanger), 64, or auto.
jpayne@69 63 statscolumns=3 (cols) Number of columns for stats output, 3 or 5.
jpayne@69 64 5 includes base counts.
jpayne@69 65 rename=f Rename reads to indicate which sequences they matched.
jpayne@69 66 refnames=f Use names of reference files rather than scaffold IDs.
jpayne@69 67 trd=f Truncate read and ref names at the first whitespace.
jpayne@69 68 ordered=f Set to true to output reads in same order as input.
jpayne@69 69 maxbasesout=-1 If positive, quit after writing approximately this many
jpayne@69 70 bases to out (outu/outnonmatch).
jpayne@69 71 maxbasesoutm=-1 If positive, quit after writing approximately this many
jpayne@69 72 bases to outm (outmatch).
jpayne@69 73 json=f Print to screen in json format.
jpayne@69 74
jpayne@69 75 Histogram output parameters:
jpayne@69 76 bhist=<file> Base composition histogram by position.
jpayne@69 77 qhist=<file> Quality histogram by position.
jpayne@69 78 qchist=<file> Count of bases with each quality value.
jpayne@69 79 aqhist=<file> Histogram of average read quality.
jpayne@69 80 bqhist=<file> Quality histogram designed for box plots.
jpayne@69 81 lhist=<file> Read length histogram.
jpayne@69 82 phist=<file> Polymer length histogram.
jpayne@69 83 gchist=<file> Read GC content histogram.
jpayne@69 84 enthist=<file> Read entropy histogram.
jpayne@69 85 ihist=<file> Insert size histogram, for paired reads in mapped sam.
jpayne@69 86 gcbins=100 Number gchist bins. Set to 'auto' to use read length.
jpayne@69 87 maxhistlen=6000 Set an upper bound for histogram lengths; higher uses
jpayne@69 88 more memory. The default is 6000 for some histograms
jpayne@69 89 and 80000 for others.
jpayne@69 90
jpayne@69 91 Histograms for mapped sam/bam files only:
jpayne@69 92 histbefore=t Calculate histograms from reads before processing.
jpayne@69 93 ehist=<file> Errors-per-read histogram.
jpayne@69 94 qahist=<file> Quality accuracy histogram of error rates versus quality
jpayne@69 95 score.
jpayne@69 96 indelhist=<file> Indel length histogram.
jpayne@69 97 mhist=<file> Histogram of match, sub, del, and ins rates by position.
jpayne@69 98 idhist=<file> Histogram of read count versus percent identity.
jpayne@69 99 idbins=100 Number idhist bins. Set to 'auto' to use read length.
jpayne@69 100 varfile=<file> Ignore substitution errors listed in this file when
jpayne@69 101 calculating error rates. Can be generated with
jpayne@69 102 CallVariants.
jpayne@69 103 vcf=<file> Ignore substitution errors listed in this VCF file
jpayne@69 104 when calculating error rates.
jpayne@69 105 ignorevcfindels=t Also ignore indels listed in the VCF.
jpayne@69 106
jpayne@69 107 Processing parameters:
jpayne@69 108 k=27 Kmer length used for finding contaminants. Contaminants
jpayne@69 109 shorter than k will not be found. k must be at least 1.
jpayne@69 110 rcomp=t Look for reverse-complements of kmers in addition to
jpayne@69 111 forward kmers.
jpayne@69 112 maskmiddle=t (mm) Treat the middle base of a kmer as a wildcard, to
jpayne@69 113 increase sensitivity in the presence of errors.
jpayne@69 114 minkmerhits=1 (mkh) Reads need at least this many matching kmers
jpayne@69 115 to be considered as matching the reference.
jpayne@69 116 minkmerfraction=0.0 (mkf) A reads needs at least this fraction of its total
jpayne@69 117 kmers to hit a ref, in order to be considered a match.
jpayne@69 118 If this and minkmerhits are set, the greater is used.
jpayne@69 119 mincovfraction=0.0 (mcf) A reads needs at least this fraction of its total
jpayne@69 120 bases to be covered by ref kmers to be considered a match.
jpayne@69 121 If specified, mcf overrides mkh and mkf.
jpayne@69 122 hammingdistance=0 (hdist) Maximum Hamming distance for ref kmers (subs only).
jpayne@69 123 Memory use is proportional to (3*K)^hdist.
jpayne@69 124 qhdist=0 Hamming distance for query kmers; impacts speed, not memory.
jpayne@69 125 editdistance=0 (edist) Maximum edit distance from ref kmers (subs
jpayne@69 126 and indels). Memory use is proportional to (8*K)^edist.
jpayne@69 127 hammingdistance2=0 (hdist2) Sets hdist for short kmers, when using mink.
jpayne@69 128 qhdist2=0 Sets qhdist for short kmers, when using mink.
jpayne@69 129 editdistance2=0 (edist2) Sets edist for short kmers, when using mink.
jpayne@69 130 forbidn=f (fn) Forbids matching of read kmers containing N.
jpayne@69 131 By default, these will match a reference 'A' if
jpayne@69 132 hdist>0 or edist>0, to increase sensitivity.
jpayne@69 133 removeifeitherbad=t (rieb) Paired reads get sent to 'outmatch' if either is
jpayne@69 134 match (or either is trimmed shorter than minlen).
jpayne@69 135 Set to false to require both.
jpayne@69 136 trimfailures=f Instead of discarding failed reads, trim them to 1bp.
jpayne@69 137 This makes the statistics a bit odd.
jpayne@69 138 findbestmatch=f (fbm) If multiple matches, associate read with sequence
jpayne@69 139 sharing most kmers. Reduces speed.
jpayne@69 140 skipr1=f Don't do kmer-based operations on read 1.
jpayne@69 141 skipr2=f Don't do kmer-based operations on read 2.
jpayne@69 142 ecco=f For overlapping paired reads only. Performs error-
jpayne@69 143 correction with BBMerge prior to kmer operations.
jpayne@69 144 recalibrate=f (recal) Recalibrate quality scores. Requires calibration
jpayne@69 145 matrices generated by CalcTrueQuality.
jpayne@69 146 sam=<file,file> If recalibration is desired, and matrices have not already
jpayne@69 147 been generated, BBDuk will create them from the sam file.
jpayne@69 148 amino=f Run in amino acid mode. Some features have not been
jpayne@69 149 tested, but kmer-matching works fine. Maximum k is 12.
jpayne@69 150
jpayne@69 151 Speed and Memory parameters:
jpayne@69 152 threads=auto (t) Set number of threads to use; default is number of
jpayne@69 153 logical processors.
jpayne@69 154 prealloc=f Preallocate memory in table. Allows faster table loading
jpayne@69 155 and more efficient memory usage, for a large reference.
jpayne@69 156 monitor=f Kill this process if it crashes. monitor=600,0.01 would
jpayne@69 157 kill after 600 seconds under 1% usage.
jpayne@69 158 minrskip=1 (mns) Force minimal skip interval when indexing reference
jpayne@69 159 kmers. 1 means use all, 2 means use every other kmer, etc.
jpayne@69 160 maxrskip=1 (mxs) Restrict maximal skip interval when indexing
jpayne@69 161 reference kmers. Normally all are used for scaffolds<100kb,
jpayne@69 162 but with longer scaffolds, up to maxrskip-1 are skipped.
jpayne@69 163 rskip= Set both minrskip and maxrskip to the same value.
jpayne@69 164 If not set, rskip will vary based on sequence length.
jpayne@69 165 qskip=1 Skip query kmers to increase speed. 1 means use all.
jpayne@69 166 speed=0 Ignore this fraction of kmer space (0-15 out of 16) in both
jpayne@69 167 reads and reference. Increases speed and reduces memory.
jpayne@69 168 Note: Do not use more than one of 'speed', 'qskip', and 'rskip'.
jpayne@69 169
jpayne@69 170 Trimming/Filtering/Masking parameters:
jpayne@69 171 Note - if ktrim, kmask, and ksplit are unset, the default behavior is kfilter.
jpayne@69 172 All kmer processing modes are mutually exclusive.
jpayne@69 173 Reads only get sent to 'outm' purely based on kmer matches in kfilter mode.
jpayne@69 174
jpayne@69 175 ktrim=f Trim reads to remove bases matching reference kmers, plus
jpayne@69 176 all bases to the left or right.
jpayne@69 177 Values:
jpayne@69 178 f (don't trim),
jpayne@69 179 r (trim to the right),
jpayne@69 180 l (trim to the left)
jpayne@69 181 ktrimtips=0 Set this to a positive number to perform ktrim on both
jpayne@69 182 ends, examining only the outermost X bases.
jpayne@69 183 kmask= Replace bases matching ref kmers with another symbol.
jpayne@69 184 Allows any non-whitespace character, and processes short
jpayne@69 185 kmers on both ends if mink is set. 'kmask=lc' will
jpayne@69 186 convert masked bases to lowercase.
jpayne@69 187 maskfullycovered=f (mfc) Only mask bases that are fully covered by kmers.
jpayne@69 188 ksplit=f For single-ended reads only. Reads will be split into
jpayne@69 189 pairs around the kmer. If the kmer is at the end of the
jpayne@69 190 read, it will be trimmed instead. Singletons will go to
jpayne@69 191 out, and pairs will go to outm. Do not use ksplit with
jpayne@69 192 other operations such as quality-trimming or filtering.
jpayne@69 193 mink=0 Look for shorter kmers at read tips down to this length,
jpayne@69 194 when k-trimming or masking. 0 means disabled. Enabling
jpayne@69 195 this will disable maskmiddle.
jpayne@69 196 qtrim=f Trim read ends to remove bases with quality below trimq.
jpayne@69 197 Performed AFTER looking for kmers. Values:
jpayne@69 198 rl (trim both ends),
jpayne@69 199 f (neither end),
jpayne@69 200 r (right end only),
jpayne@69 201 l (left end only),
jpayne@69 202 w (sliding window).
jpayne@69 203 trimq=6 Regions with average quality BELOW this will be trimmed,
jpayne@69 204 if qtrim is set to something other than f. Can be a
jpayne@69 205 floating-point number like 7.3.
jpayne@69 206 trimclip=f Trim soft-clipped bases from sam files.
jpayne@69 207 minlength=10 (ml) Reads shorter than this after trimming will be
jpayne@69 208 discarded. Pairs will be discarded if both are shorter.
jpayne@69 209 mlf=0 (minlengthfraction) Reads shorter than this fraction of
jpayne@69 210 original length after trimming will be discarded.
jpayne@69 211 maxlength= Reads longer than this after trimming will be discarded.
jpayne@69 212 minavgquality=0 (maq) Reads with average quality (after trimming) below
jpayne@69 213 this will be discarded.
jpayne@69 214 maqb=0 If positive, calculate maq from this many initial bases.
jpayne@69 215 minbasequality=0 (mbq) Reads with any base below this quality (after
jpayne@69 216 trimming) will be discarded.
jpayne@69 217 maxns=-1 If non-negative, reads with more Ns than this
jpayne@69 218 (after trimming) will be discarded.
jpayne@69 219 mcb=0 (minconsecutivebases) Discard reads without at least
jpayne@69 220 this many consecutive called bases.
jpayne@69 221 ottm=f (outputtrimmedtomatch) Output reads trimmed to shorter
jpayne@69 222 than minlength to outm rather than discarding.
jpayne@69 223 tp=0 (trimpad) Trim this much extra around matching kmers.
jpayne@69 224 tbo=f (trimbyoverlap) Trim adapters based on where paired
jpayne@69 225 reads overlap.
jpayne@69 226 strictoverlap=t Adjust sensitivity for trimbyoverlap mode.
jpayne@69 227 minoverlap=14 Require this many bases of overlap for detection.
jpayne@69 228 mininsert=40 Require insert size of at least this for overlap.
jpayne@69 229 Should be reduced to 16 for small RNA sequencing.
jpayne@69 230 tpe=f (trimpairsevenly) When kmer right-trimming, trim both
jpayne@69 231 reads to the minimum length of either.
jpayne@69 232 forcetrimleft=0 (ftl) If positive, trim bases to the left of this position
jpayne@69 233 (exclusive, 0-based).
jpayne@69 234 forcetrimright=0 (ftr) If positive, trim bases to the right of this position
jpayne@69 235 (exclusive, 0-based).
jpayne@69 236 forcetrimright2=0 (ftr2) If positive, trim this many bases on the right end.
jpayne@69 237 forcetrimmod=0 (ftm) If positive, right-trim length to be equal to zero,
jpayne@69 238 modulo this number.
jpayne@69 239 restrictleft=0 If positive, only look for kmer matches in the
jpayne@69 240 leftmost X bases.
jpayne@69 241 restrictright=0 If positive, only look for kmer matches in the
jpayne@69 242 rightmost X bases.
jpayne@69 243 NOTE: restrictleft and restrictright are mutually exclusive. If trimming
jpayne@69 244 both ends is desired, use ktrimtips.
jpayne@69 245 mingc=0 Discard reads with GC content below this.
jpayne@69 246 maxgc=1 Discard reads with GC content above this.
jpayne@69 247 gcpairs=t Use average GC of paired reads.
jpayne@69 248 Also affects gchist.
jpayne@69 249 tossjunk=f Discard reads with invalid characters as bases.
jpayne@69 250 swift=f Trim Swift sequences: Trailing C/T/N R1, leading G/A/N R2.
jpayne@69 251
jpayne@69 252 Header-parsing parameters - these require Illumina headers:
jpayne@69 253 chastityfilter=f (cf) Discard reads with id containing ' 1:Y:' or ' 2:Y:'.
jpayne@69 254 barcodefilter=f Remove reads with unexpected barcodes if barcodes is set,
jpayne@69 255 or barcodes containing 'N' otherwise. A barcode must be
jpayne@69 256 the last part of the read header. Values:
jpayne@69 257 t: Remove reads with bad barcodes.
jpayne@69 258 f: Ignore barcodes.
jpayne@69 259 crash: Crash upon encountering bad barcodes.
jpayne@69 260 barcodes= Comma-delimited list of barcodes or files of barcodes.
jpayne@69 261 xmin=-1 If positive, discard reads with a lesser X coordinate.
jpayne@69 262 ymin=-1 If positive, discard reads with a lesser Y coordinate.
jpayne@69 263 xmax=-1 If positive, discard reads with a greater X coordinate.
jpayne@69 264 ymax=-1 If positive, discard reads with a greater Y coordinate.
jpayne@69 265
jpayne@69 266 Polymer trimming:
jpayne@69 267 trimpolya=0 If greater than 0, trim poly-A or poly-T tails of
jpayne@69 268 at least this length on either end of reads.
jpayne@69 269 trimpolygleft=0 If greater than 0, trim poly-G prefixes of at least this
jpayne@69 270 length on the left end of reads. Does not trim poly-C.
jpayne@69 271 trimpolygright=0 If greater than 0, trim poly-G tails of at least this
jpayne@69 272 length on the right end of reads. Does not trim poly-C.
jpayne@69 273 trimpolyg=0 This sets both left and right at once.
jpayne@69 274 filterpolyg=0 If greater than 0, remove reads with a poly-G prefix of
jpayne@69 275 at least this length (on the left).
jpayne@69 276 Note: there are also equivalent poly-C flags.
jpayne@69 277
jpayne@69 278 Polymer tracking:
jpayne@69 279 pratio=base,base 'pratio=G,C' will print the ratio of G to C polymers.
jpayne@69 280 plen=20 Length of homopolymers to count.
jpayne@69 281
jpayne@69 282 Entropy/Complexity parameters:
jpayne@69 283 entropy=-1 Set between 0 and 1 to filter reads with entropy below
jpayne@69 284 that value. Higher is more stringent.
jpayne@69 285 entropywindow=50 Calculate entropy using a sliding window of this length.
jpayne@69 286 entropyk=5 Calculate entropy using kmers of this length.
jpayne@69 287 minbasefrequency=0 Discard reads with a minimum base frequency below this.
jpayne@69 288 entropytrim=f Values:
jpayne@69 289 f: (false) Do not entropy-trim.
jpayne@69 290 r: (right) Trim low entropy on the right end only.
jpayne@69 291 l: (left) Trim low entropy on the left end only.
jpayne@69 292 rl: (both) Trim low entropy on both ends.
jpayne@69 293 entropymask=f Values:
jpayne@69 294 f: (filter) Discard low-entropy sequences.
jpayne@69 295 t: (true) Mask low-entropy parts of sequences with N.
jpayne@69 296 lc: Change low-entropy parts of sequences to lowercase.
jpayne@69 297 entropymark=f Mark each base with its entropy value. This is on a scale
jpayne@69 298 of 0-41 and is reported as quality scores, so the output
jpayne@69 299 should be fastq or fasta+qual.
jpayne@69 300 NOTE: If set, entropytrim overrides entropymask.
jpayne@69 301
jpayne@69 302 Cardinality estimation:
jpayne@69 303 cardinality=f (loglog) Count unique kmers using the LogLog algorithm.
jpayne@69 304 cardinalityout=f (loglogout) Count unique kmers in output reads.
jpayne@69 305 loglogk=31 Use this kmer length for counting.
jpayne@69 306 loglogbuckets=2048 Use this many buckets for counting.
jpayne@69 307 khist=<file> Kmer frequency histogram; plots number of kmers versus
jpayne@69 308 kmer depth. This is approximate.
jpayne@69 309 khistout=<file> Kmer frequency histogram for output reads.
jpayne@69 310
jpayne@69 311 Java Parameters:
jpayne@69 312
jpayne@69 313 -Xmx This will set Java's memory usage, overriding autodetection.
jpayne@69 314 -Xmx20g will
jpayne@69 315 specify 20 gigs of RAM, and -Xmx200m will specify 200 megs.
jpayne@69 316 The max is typically 85% of physical memory.
jpayne@69 317 -eoom This flag will cause the process to exit if an
jpayne@69 318 out-of-memory exception occurs. Requires Java 8u92+.
jpayne@69 319 -da Disable assertions.
jpayne@69 320
jpayne@69 321 Please contact Brian Bushnell at bbushnell@lbl.gov if you encounter any problems.
jpayne@69 322 "
jpayne@69 323 }
jpayne@69 324
jpayne@69 325 #This block allows symlinked shellscripts to correctly set classpath.
jpayne@69 326 pushd . > /dev/null
jpayne@69 327 DIR="${BASH_SOURCE[0]}"
jpayne@69 328 while [ -h "$DIR" ]; do
jpayne@69 329 cd "$(dirname "$DIR")"
jpayne@69 330 DIR="$(readlink "$(basename "$DIR")")"
jpayne@69 331 done
jpayne@69 332 cd "$(dirname "$DIR")"
jpayne@69 333 DIR="$(pwd)/"
jpayne@69 334 popd > /dev/null
jpayne@69 335
jpayne@69 336 #DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
jpayne@69 337 CP="$DIR""current/"
jpayne@69 338 JNI="-Djava.library.path=""$DIR""jni/"
jpayne@69 339 JNI=""
jpayne@69 340
jpayne@69 341 z="-Xmx1g"
jpayne@69 342 z2="-Xms1g"
jpayne@69 343 set=0
jpayne@69 344 silent=0
jpayne@69 345 json=0
jpayne@69 346
jpayne@69 347 if [ -z "$1" ] || [[ $1 == -h ]] || [[ $1 == --help ]]; then
jpayne@69 348 usage
jpayne@69 349 exit
jpayne@69 350 fi
jpayne@69 351
jpayne@69 352 calcXmx () {
jpayne@69 353 source "$DIR""/calcmem.sh"
jpayne@69 354 setEnvironment
jpayne@69 355 parseXmx "$@"
jpayne@69 356 if [[ $set == 1 ]]; then
jpayne@69 357 return
jpayne@69 358 fi
jpayne@69 359 freeRam 1400m 42
jpayne@69 360 z="-Xmx${RAM}m"
jpayne@69 361 z2="-Xms${RAM}m"
jpayne@69 362 }
jpayne@69 363 calcXmx "$@"
jpayne@69 364
jpayne@69 365 bbduk() {
jpayne@69 366 local CMD="java $EA $EOOM $z $z2 $JNI -cp $CP jgi.BBDuk $@"
jpayne@69 367 if [[ $silent == 0 ]] && [[ $json == 0 ]]; then
jpayne@69 368 echo $CMD >&2
jpayne@69 369 fi
jpayne@69 370 eval $CMD
jpayne@69 371 }
jpayne@69 372
jpayne@69 373 bbduk "$@"