Reputation: 11327
I have a simple bat script that copies files from an known directory to a directory given by the user. How can I pass the path (it might contain spaces) to my script and use it with the xcopy command?
In my code i have the following
:READ_PWA_PATH
if "%1" == "" (
rem Set default path
set PWA_PATH="C:\Program Files\PWA"
rem
echo You have not specified your PWA url.
echo Default will be assumed: C:\Program Files\PWA.
choice /C:YN /M:"Do you wish to continue [Y] or cancel the script [N]?"
IF ERRORLEVEL ==2 GOTO CANCEL
IF ERRORLEVEL ==1 GOTO READ_WSS_SERVER_EXTENSIONS_PATH
GOTO END
) else (
set PWA_PATH=%1
)
If I simply call the script I get the following error:
C:\Projects\Setup>install.cmd "C:\program files (x86)"
-----------------
SETUP SCRIPT
-----------------
files was unexpected at this time.
C:\Projects\Setup>
Upvotes: 86
Views: 229163
Reputation: 17970
In a special case scenario, where you want to always default to the current directory always, OR, default to the current directory only if a parameter was not passed in, you can use %CD%
.
As found per this answer on Server Fault:
Windows maintains the current directory in the psuedo-environment variable
%CD%
.
Check out that post for a great example and how your can easily test it directly via the command line.
In my case, I an an app (myapp.exe
) that I needed to call with a command-line flag --dir=
, like:
myapp --dir=<path-to-desired-directory>
.
Since I always wanted the flag to always reference whichever directory I called the app from, I could make a batch file (mybat.bat
) to automatically capture my current path, and open the app with it.
mybat .
worked when mybat.bat had the following contents:
myapp --dir=%1
Which was great, but being able to leave off the .
was even better.
mybat
works when I changed the contents to:
myapp --dir=%CD%
Upvotes: 0
Reputation: 526
Suppose you want to backup a database by executing a batch file from within a C# code. Here is a fully working solution that deals with blank spaces inside the path. This works in Windows. I have not tested it with mono though.
C# code:
public bool BackupDatabase()
{
bool res = true;
string file = "db.bat";
if (!File.Exists(file)) return false;
BackupPaths.ForEach(path =>
{
Directory.CreateDirectory(path);
string filePath = Path.Combine(path, string.Format("{0}_{1}.bak", Util.ConvertDateTimeToFileName(false), DatabaseName));
Process process = new Process();
process.StartInfo.FileName = file;
process.StartInfo.Arguments = string.Format(" {0} {1} \\\"{2}\\\""
, DBServerName
, DatabaseName
, filePath);
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
try
{
process.Start();
process.WaitForExit();
}
catch (Exception ee)
{
Logger.Log(ee);
res = false;
}
});
return res;
}
and here is the batch file:
@echo OFF
set DB_ServerName=%1
set Name_of_Database=%2
set PathToBackupLocation=%3
echo Server Name = '%DB_ServerName%'
echo Name of Database = '%Name_of_Database%'
echo Path To Backup Location = '%PathToBackupLocation%'
osql -S %DB_ServerName% -E -Q "BACKUP DATABASE %Name_of_Database% TO DISK=%PathToBackupLocation%"
Upvotes: 0
Reputation: 1481
Use "%~1"
. %~1
alone removes surrounding quotes. However since you can't know whether the input parameter %1
has quotes or not, you should ensure by "%~1"
that they are added for sure. This is especially helpful when concatenating variables, e.g. convert.exe "%~1.input" "%~1.output"
Upvotes: 148
Reputation: 724
"%~1" will work most of the time. However there are a few things you need to note for this:
To demonstrate second point, let me give an example:
REM example.cmd
ECHO %~1
Run with example.cmd dummy^&DIR
. The ampersand is escaped here ( ^&
) to prevent shell from interpreting as a command delimiter, so that it becomes part of the argument passed to the script. The DIR is interpreted as a command inside the sub-shell running the script, where it shouldn't.
Quoting it might work some time, but still insecure:
REM example2.cmd
SETLOCAL EnableExtensions EnableDelayedExpansion
SET "arg1=%~1"
ECHO "%~1"
ECHO !arg1:"=!
example2.cmd foo^"^&DIR^&^"bar
will break it. DIR command will be run two times, one right after SET and the other right after the first ECHO. You see that the "%~1"
you think is quoted well gets unquoted by the argument itself.
So, no way to make parsing arguments secure.
(EDIT: EnableDelayedExpansion
doesn't work in Windows NT 4 either. Thanks to the info here: http://www.robvanderwoude.com/local.php)
Upvotes: 7
Reputation: 71
If your path contains space then try using %~s1
. This will remove the space and appends ~1
to your path and more importantly it refers to the absolute path of your file. Try using it.
Upvotes: 2
I think the OP's problem was that he wants to do BOTH of the following:
As several posters have mentioned, to pass a parameter containing spaces, you must surround the actual parameter value with double quotes.
To test whether a parameter is missing, the method I always learned was:
if "%1" == ""
However, if the actual parameter is quoted (as it must be if the value contains spaces), this becomes
if ""actual parameter value"" == ""
which causes the "unexpected" error. If you instead use
if %1 == ""
then the error no longer occurs for quoted values. But in that case, the test no longer works when the value is missing -- it becomes
if == ""
To fix this, use any other characters (except ones with special meaning to DOS) instead of quotes in the test:
if [%1] == []
if .%1. == ..
if abc%1xyz == abcxyz
Upvotes: 17
Reputation: 1328602
@echo off
setlocal enableextensions enabledelayedexpansion
if %1=="" (
rem Set default path
set PWA_PATH="C:\Program Files\PWA"
rem
echo You have not specified your PWA url.
echo Default will be assumed: C:\Program Files\PWA.
choice /C:YN /M:"Do you wish to continue [Y] or cancel the script [N]?"
IF ERRORLEVEL ==2 GOTO CANCEL
IF ERRORLEVEL ==1 GOTO READ_WSS_SERVER_EXTENSIONS_PATH
GOTO END
) else (
set PWA_PATH=%1
@echo !PWA_PATH! vs. %1
goto end
)
:READ_WSS_SERVER_EXTENSIONS_PATH
echo ok
goto end
:CANCEL
echo cancelled
:end
echo. final %PWA_PATH% vs. %1
As VardhanDotNet mentions, %1
is enough.
"%1%"
would add quotes around quotes: ""c:\Program Files\xxx""
which means:
""
), ""
)Note however that if you need to use PWA_PATH
within your IF
clause, you need to refer if as !PWA_PATH!
(hence the enabledelayedexpansion
as the beginning of the script)
Upvotes: 2
Reputation:
Interesting one. I love collecting quotes about quotes handling in cmd/command.
Your particular scripts gets fixed by using %1 instead of "%1" !!!
By adding an 'echo on' ( or getting rid of an echo off ), you could have easily found that out.
Upvotes: 20
Reputation:
If you have a path with spaces you must surround it with quotation marks (").
Not sure if that's exactly what you're asking though?
Upvotes: 5