Jacob Wang
Jacob Wang

Reputation: 4804

Why multiple arguments with spaces are not interpreted correctly in a batch script?

I'm running an exe with multiple arguments that may or may not contain spaces. I encloses them with quotes but they are somehow not passed to the exe correctly.

Here's the command i'm using:

makeblastdb -in "D:\d b\sequence.fasta" -input_type fasta -dbtype prot -title xd -out "D:\d b\xd"

which I think cmd should pass 10 arguments to the exe but somehow it isn't passing correctly.

this is the result i get

BLAST options error: File "D:\d" does not exist.

which is basically saying that the second argument is being chopped for some reason?

Any help will be appreciated, thanks!

Upvotes: 1

Views: 463

Answers (4)

Tom Hall
Tom Hall

Reputation: 1

The answers here that worked for me in Windows were creating a transient virtual drive, as shown by dbenham (but this is not a viable solution for a general automated process that may be run on different computers and would be inefficient and impractical for multiple parallel threaded operations) or getting the short path string as pointed out by Jugal Shah (which is not always convenient, as it requires unmanaged code accessing kernel32.dll to utilize in C#, for example). However, it's an easy fix if you recompile the necessary blast project files from the source code.

If you are able to download the blast project code (e.g. version 2.12.0 from https://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/2.12.0/), you can rebuild makeblastdb.exe after modifying just two lines of code, and after rebuilding makeblastdb, db targets enclosed in quotes should work correctly when there are spaces in the path. Note: This was tested with v2.12.0 in Windows 11 with Visual Studio 2019, after first following project configuration instructions included with the ncbi code package and building and testing makeblastdb.exe, blastn.exe and blast_formatter.exe.

Lines of code to modify:

-- In .\ncbi-blast-2.12.0\c++\src\app\blastdb\makeblastdb.cpp, line 202 reads (if not line 202, close to it):

static const string kInputSeparators(" ");

To change the multi-input separator to, for example, a comma instead of a space, change it to:

static const string kInputSeparators(",");

-- In .\ncbi-blast-2.12.0\c++\src\objtools\blast\seqdb_reader\seqdbcommon.cpp, line 1789 reads (if not line 1789, close to it):

if (ch == ' ') {

Change it to:

if (ch == ',') {

Rebuild makeblastdb.exe and the problem should be solved. Enclose the target "-in" path in quotes and it should no longer be parsed into space-delimited strings.

If you want other programs (e.g. blastn, blast_formatter, etc.) to work correctly with quote-enclosed paths with spaces in the path, those modules will need to be rebuilt as well.

Upvotes: 0

Craig W
Craig W

Reputation: 4540

makeblastdb has an odd escaping convention. Try this:

-in \""D:\d b\sequence.fasta"\"

Unfortunately this doesn't work for -out, so dbenham's answer is probably best.

Upvotes: 2

dbenham
dbenham

Reputation: 130919

Based on your comments to your question, the BLAST utility does not properly handle quoted paths with spaces, and your volume does not support short file names.

Obviously you can move your working directory to a path that does not contain spaces.

An alternative is to use SUBST to temporarily create a virtual drive that points to your problematic path.

subst K: "d:\d b"
makeblastdb -in "K:\sequence.fasta" -input_type fasta -dbtype prot -title xd -out "K:\xd"
subst /d K:

Type subst /? for help with the command.

Update based on fact that you are running the command from within python

In your comment to this answer, you state you will attempt to get the command to work from within python. That could be the entire source of your problem.

You should try to run the command in your question directly from a Windows command prompt (cmd.exe console).

If the command does not work from the command prompt, then the problem is indeed with the BLAST utility, and SUBST is a good solution.

If the command does work from the command prompt, then the problem is with how you are shelling out the command from python, and the SUBST command should not be required.

I'm not a python user, but I see that many people have similar problems when using python on Windows. Perhaps this will help: How do I execute a program from python? os.system fails due to spaces in path

Upvotes: 3

Jugal Shah
Jugal Shah

Reputation: 3695

Alternative is you can try using directory shortname for "D:\d b" which you can find by running dir /X command on your D drive. For instance if I run dir /X on my C drive here is what I get:

01/21/2013    09:47 AM    <DIR>      PROGRA~1     Program Files

So you want to use C:\Program Files you can alternatively use C:\PROGRA~1.

Upvotes: 0

Related Questions