1

I need to call a script which accepts password as one of its arguments. Whenever the password contains , it is treated as a delimiter and the password will be split into two arguments and when it contains ! all the special characters are omitted. I have tried enclosing them in ', " and preprocessing the password to escape with both ^ and ^^. Unfortunately, nothing worked. How to preserve these special characters in the password?

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Pramod
  • 391
  • 5
  • 21

1 Answers1

3

You are right, delayed expansion has to be turned of (temporarily) for that to work properly. The ! has to be escaped (for the delayed part later) and quoting takes care of the rest:

@echo off
setlocal enabledelayedexpansion

REM --- get parameter ---
setlocal disabledelayedexpansion
set "x=%~1"
endlocal & set "x=%x:!=^!%"
REM --- end get param ---

set x
echo "!x!"

Output:

C:\TEST>test.bat "pass,!<& %|>word"
x=pass,!<& %|>word
"pass,!<& %|>word"

The main trick is the line endlocal & set "x=%x:!=^!%". The set command is still parsed without delayed expansion, but executed after endlocal (as the whole line is parsed before anything gets executed - yes, strange thing...)

Stephan
  • 53,940
  • 10
  • 58
  • 91
  • @aschipfl yes and no - depends on where it is (they are) in relation to other poison chars. (I think I remember a bulletproof method (by dbenham, I think), but can't find it right now - as far as I remember that was far more code though) – Stephan Apr 22 '20 at 20:40
  • I guess it makes use of the built-in variable `CmdCmdLine`, which can be accessed with delayed expansion, but then you'd have to do the argument separation on your own... – aschipfl Apr 22 '20 at 20:43
  • @aschipfl oh, and `^` is another troublesome candidate. – Stephan Apr 22 '20 at 20:50
  • Ah, because of delayed expansion, I think? – aschipfl Apr 22 '20 at 20:52
  • @aschipfl that's only half the truth. Also `set` treats it as an escape char and suppresses it. – Stephan Apr 23 '20 at 07:03