I am writing a Lua script to manage Virtualbox on windows.
It seems that multiple double quotes are not parsed correctly. I am using the following function to implement this:
--Get output from an OS command - http://stackoverflow.com/questions/132397/get-back-the-output-of-os-execute-in-lua
function os.capture(cmd, raw)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
if raw then return s end
s = string.gsub(s, '^%s+', '')
s = string.gsub(s, '%s+$', '')
s = string.gsub(s, '[\n\r]+', ' ')
return s
end
This code works so long an the machine name doesn't have a space, but machines can have spaces so I have to support them:
local command = '"\\Program Files\\Oracle\\VirtualBox\\VBoxManage\" showvminfo '..key
The following code does not work at all but it does give the correct format of the command to the log file so the syntax should be correct:
local command = '"\\Program Files\\Oracle\\VirtualBox\\VBoxManage\" showvminfo "'..key..'"'
logger:write("[",os.date("%Y-%m-%d %H:%M:%S"),"] Command: ",command,"\n")
vmStateRaw = os.capture(command, "raw")
Log file entry:
[2014-12-06 16:09:18] Command: "\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"
Interpreter output:
'\Program' is not recognized as an internal or external command,
operable program or batch file.
I have found that the following syntax works:
local command = '""\\Program Files\\Oracle\\VirtualBox\\VBoxManage\" showvminfo "'..key..'"'
Log file output:
[2014-12-06 16:27:54] Command: ""\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"
So this question isn't to solve a problem as I have aleady done that. I want to understand why the last command works as my current understand means this should not work.
TIA
The issue has to do with how system in C works. Under windows, system internally calls
cmd /c yourinput
Since os.execute just delegates to system (see here), your command likely ends up executing as:
cmd /c "\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"
For reference, from help cmd:
If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:
If all of the following conditions are met, then quote characters
on the command line are preserved:
no /S switch
exactly two quote characters
no special characters between the two quote characters,
where special is one of: &<>()#^|
there are one or more whitespace characters between the
two quote characters
the string between the two quote characters is the name
of an executable file.
Otherwise, old behavior is to see if the first character is
a quote character and if so, strip the leading character and
remove the last quote character on the command line, preserving
any text after the last quote character.
Since your command contains 4 double quotes in there, it parses your command with the old behavior. This is why you need to surround your entire command with an extra set of " double quotes.
Related
I'm trying to parse a few commands to Houdini's Python module called Hython.
And I'm doing this through os on windows.
My command looks like this:
command = '''"c:\\Program Files (x86)\\Steam\\steamapps\\common\\Houdini Indie\\bin\\hython.exe" -c \
"import sys; sys.path.append('d:\\Cloud\\OneDrive\\Dokumenter\\GitHub\\tutorialTools\\utils'); \
import houUtils; houUtils.runReduction(\'%s\',\'%s\')"''' % (assetDir, amount)
os.popen(command)
I've tried all the tricks on quotations I could think of, but I'm getting a :
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes
in position 49-50: truncated \uXXXX escape
Any kind of help would be appreciated
First I tried adding to the command by separate lines:
"command +=" but this stopped me quickly.
I've tried doing the initial path with r'c:\...'
The entire problem seems to be connected with writing paths inside a quotation.
Hello I have been trying to get user input and store it in a variable, and then use that variable in a CMD. ALL of this in a DXL script!
Take a glance into the code I have tried this but still not working.
string wheretosave = ""
DB exBox = create "Get Path"
DBE stringInn = field(exBox, "ADD Path where to save:", "", 80)
void doGet(DB exBox) {
wheretosave = get stringInn
print wheretosave "\n"
system("cmd.exe /C cd /d wheretosave & dir & PAUSE")
}
apply(exBox, "Get", doGet)
show exBox
to add "wheretosave" to a string, use
system("cmd.exe /C cd /d " wheretosave " & dir & PAUSE")
But I think the system call does not work. When I start a command line and do a command
cmd.exe /C cd /d d:\temp & dir & PAUSE
then I get the dir of the original directory.
#root: ADDITION: my problem was that I did not have a directory d:\temp on my PC...
But after reading your comment, it seems the point was not understood.
To be more precise:
First: there is no interpolation in DXL. If you want to create a string which contains a) some fixed characters, b) the content of a variable (here: wheretosave) and c) some more fixed characters, you have to use a < space > to concanate the three parts. So, do it like this: string s1 = "fixedtexta" wheretosave "fixedtextb".
Second: If the fixed characters contains a quotation mark then you have to escape it with a backslash. So, this example would become to string s2 = "fixedtexta\"" wheretosave "\"fixedtextb" to get fixedtexta"hello world"fixedtextb if wheretosavecontains hello world
BUT your example is even more difficult.
Third: cmd.exe /C takes only one parameter. So, if you want to do more than one command in the cmd subshell, you have to surround all the commands with enclosing quotation marks cmd.exe /C "cmd 1 & cmd 2 & cmd 3" The way you wrote it would have translated to
create a subshell which does a "cd /d", end the subshell
in the main shell (which is still in the original directory), do a "dir"
in the main shell, do a "pause"
Fourth: In DOS, if you have a quotation mark inside a string, you have to escape it with a second quotation mark.
All in all the command you are looking for is
string wheretosave = "d:\\temp x" // or get stringInn in your example
system("cmd.exe /C \"cd /d \"\"" wheretosave "\"\" & dir & pause\"")
Try providing the full path and apply Mike's correction. Using "C:\Windows" works as expected (for me): the cmd shows the content of my Windows folder on drive C.
I use windows 7 pro service pack 1.
I have the following code in the post build event :
SET VAR1=BLABLA
ECHO %VAR1% > Test.txt
It wont work. In the file, i get «command echo activated» (translated from french).
Embarcadero documentation says that i can use any valid dos command in those events.
If i just use :
ECHO BLABLA > Test.txt
It works, no problem. Is this a bug or there is a problem with % character ? % is an ascii char so i dont even know what could be the problem.
ty for your help.
% is used in cmd to delimit variablenames when the value of the variable is required, hence echo %var1% > test.txt will write the current value of the environment variable var1 to the file.
If var1 is not defined at the time, it will report the echo status (Echo is on/off`.
This can be circumvented by using echo(%var1% - the ( modifies echo's behaviour to not report the echo status if the arguments are resolved to nothing.
If you want to echo a literal % then you need to escape the % with another %. cmd normally uses ^ to escape symbols with a special meaning - % is the exception; %% to echo a literal %.
BTW - the space between the string to be echoed and the redirector will be output to the file. To prevent this, use > test.txt echo %var1% Note that > creates a file anew. >> will create or append if the file already exists. The space between the redirector and the filename is optional.
However, it's important when using batch to post exactly the code that's in use.
SET VAR1=BLABLA
ECHO %VAR1% > Test.txt
will work happily.
SET VAR1 = BLABLA
ECHO %VAR1% > Test.txt
will not because this latter code sets a variable named "var1Space"
On my 10.2.1 system, I've tried the code as published.
The actual code that's executed is
SET VAR1=BLABLA&ECHO %VAR1% > Test.txt
not
SET VAR1=BLABLA
ECHO %VAR1% > Test.txt
as shown in the "Build events commands" window.
This will not work because the entire line is executed as published on the "build events" page - SET VAR1=BLABLA&ECHO %VAR1% > Test.txt which will be interpreted by cmd after cmd performs its standard parsing routine.
cmd replaces any %var% with the actual value at parse time, not at run time hence as var1 has no value when the line SET VAR1=BLABLA&ECHO %VAR1% > Test.txt is parsed, the code is executed as SET VAR1=BLABLA&ECHO > Test.txt hence the problem encountered.
To cure this, you need to use
SET VAR1=BLABLA&call ECHO %%VAR1%% > Test.txt
where cmd will execute the parsed-ECHO command in a subshell. % is the escape character for % so the subshell executes ECHO %VAR1% > Test.txt after var1 has been set.
I'd suggest you raise this as a problem with EMBT. Batch commands cannot be strung together with & without side-effects. The code entered into the "Build events commands" window should be executed without reformatting - just written to a (temporary) batch file and the batch file then executed.
No doubt the eager downvoters will support the resolution of this problem.
Normal way to open the command-prompt in tmux is prefix + :. I want to bind the sequence prefix + ; to open the command prompt. I am too lazy to hit the shift key.
When I put this in my tmux.conf: bind-key ; command-prompt, I get this error: /Users/skilbjo/.tmux.conf:19: usage: bind-key [-cnr] [-t mode-table] [-T key-table] key command [arguments]
which is funny, because when I do prefix + ? (alias for tmux list-keys), this is listed: bind-key -T prefix : command-prompt. How does this sorcery work? I even tried bind-key -T prefix ; command-prompt to no avail, same error message
tmux uses semicolon as a command separator.
From the tmux man page:
Multiple commands may be specified together as part of a command sequence. Each command should be separated by spaces and a semicolon; commands are executed sequentially from left to right and lines ending with a backslash continue on to the next line, except when escaped by another backslash. A literal semicolon may be included by escaping it with a backslash (for example, when specifying a command sequence to bind-key).
What you'll want to do is:
unbind-key \;
bind-key \; command-prompt
I tried to invoke java inside bash script on windows (Win XP) using cygwin.
However path to java.exe contain spaces.
only literaly putting in bash sometghing like this worked:
/cygdrive/c/Program\ Files/Java/jdk1.5.0_10/bin/java -cp "$TOOL_HOME" DateParse "$DATE" "$FORMAT"
My attemts to put java path to a variable failed:
export JAVA_EXE="/cygdrive/c/Program\ Files/Java/jdk1.5.0_10/bin/java"
$JAVA_EXE -cp "$TOOL_HOME" DateParse "$DATE" "$FORMAT"
also different combination with cygpath, quotes, brackets did not work. I am not finding the the right combination
Put quotes around $JAVA_EXE:
"$JAVA_EXE" -cp "$TOOL_HOME" DateParse "$DATE" "$FORMAT"
The problem is that every time a variable is expanded, its also broken into words at spaces, UNLESS you put quotes around it. So if you don't want things broken at spaces, you need quotes.
Another alternative is to always use short (DOS) names for things, which don't allow spaces. To see what the short name is, run
cygpath -d "$JAVA_EXE"
to convert that back to a unix-like cygwin path, use
cygpath -u $(cygpath -d "$JAVA_EXE")
thank you for your ideas. It worked in proper combination. The issue was that I was escaping space character and at the same time putting JAVA_EXE in quotes.
export JAVA_EXE="/cygdrive/c/Program Files/Java/jdk1.5.0_10/bin/java"
"$JAVA_EXE" -cp "$TOOL_HOME" DateParse "$DATE" "$FORMAT"
produce this effect:
line 30: /cygdrive/c/Program\ Files/Java/jdk1.5.0_10/bin/java: No such file or directory
on the other hand, converting to DOS 8.3 does not work neither:
cannot create short name of \\?\C:\Program\ Files\Java\jdk1.5.0_10
\bin\java
Finally, putting JAVA_EXE in quotes but without escaping space in path worked fine for me:
export JAVA_EXE="/cygdrive/c/Program Files/Java/jdk1.5.0_10/bin/java"
"$JAVA_EXE" -cp "$TOOL_HOME" DateParse "$DATE" "$FORMAT"