问题
Scripting is made for CLI and, in the Microsoft world, script arguments referring to files may often have spaces requiring them to be quoted.
This turns out to be problematic for me. Consider this script:
#testarg.ps1
for($i=0; $i -lt $args.length; $i++)
{
write-host "Arg$i = $($args[$i])"
}
If I run it inside the PowerShell interactive environment, like this:
PS C:\script> .\testarg.ps1 "first arg" "second arg"
I get, as expected,
Arg0 = first arg
Arg1 = second arg
But the ordinary use of a script would be, outside the interactive mode, in a batch one. As far as I understand, the Microsoft suggested way to run scripts from cmd.exe
seems to be powershell.exe path\to\script.ps1
(without space in path). But:
powershell.exe .\testarg.ps1 "first arg" "second arg"
gives the inconsistent result:
Arg0 = first
Arg1 = arg
Arg2 = second
Arg3 = arg
I noted that to obtain the intended result I can use single quotes:
powershell.exe .\testarg.ps1 'first arg' 'second arg'
But this is often not viable when the script is to be run by GUI tools that automatically generate and pass the arguments, and/or in presence of more CLI tools for reason of consistency in the use of the quotes.
For some reason when using the -file
option:
powershell.exe –file .\testarg.ps1 "first arg" "second arg"
::(reference to relative path '.\' is optional)
I get again the intended result:
Arg0 = first arg
Arg1 = second arg
So with the -file
option the double quotes work properly. This suggests that one can remap the Windows file type association for ps1
files (with FTYPE.exe
) to something like:
FTYPE Microsoft.PowerShellScript.1=C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file "%1" %*
Given the FTYPE association, I can obtain the intended result by simply writing:
testarg.ps1 "first arg" "second arg"
The latter is quite satisfying for me, but since I am newbie with PowerShell, I wonder:
- For a general script, are the batch form
powershell.exe –file path\to\script.ps1
and the interactive form (from within PowerShell)PS > path\to\script.ps1
equivalent? Are there some instances when the two forms may produce different output/effects? - Is there a possible solution inside the script to read the command line as is (without stripping double quotes)? Something like
*%
forcmd.exe
.
回答1:
There is one thing I don't understand when you wrote:
testarg.ps1 "first arg" "second arg"
Inside which batch are you calling that?
From PowerShell.exe
, it should be written:
cd "c:\Temp"
& .\testarg.ps1 "first arg" "second arg"
From cmd.exe
it should be written:
powershell –file .\testarg.ps1 "first arg" "second arg"
来源:https://stackoverflow.com/questions/14011901/passing-quoted-arguments-to-powershell-scripts