Open gene-pavlovsky opened 8 years ago
And why do you post this here?
I'm using bashcmd, a small program I wrote to be able to use bash on Far's command line. But I think that bug can also be reproduced with a simple test program. To use bashcmd, download https://dl.dropboxusercontent.com/u/49471027/far_bash_comspec.7z The instructions are in the README files inside.
This issue doesn't happen if I run the commands from a plain Far running on it's own (without ConEmu).
If I understand correctly, ConEmuC somehow intercepts execution of any child subprocess, to be able to catch ConEmu options (e.g. -new_console
), then runs the child process with the original command line minus the ConEmu-related options, is that right?
I see there is a cmd.exe
invocation involved in the chain of processes originating from Far. This cmd process receives the correct command-line, but then doesn't pass it right because of the \"
. Why doesn't ConEmuC run the bashcmd.exe
directly, but does it via cmd.exe
? When same Far is executed without ConEmu, it runs bashcmd.exe
directly.
Bottom line.
Far tries to run bashcmd.exe
with a particular command-line.
If that happens in standalone Far, it works and bashcmd.exe
receives the correct command-line.
Under ConEmu.exe, an additional cmd.exe
gets in between Far and bashcmd.exe
, as result bashcmd.exe
doesn't receive the correct command-line because of some quoting issues (apparently, a combination of \"
followed by |
).
When the same command is run in standalone Far. No cmd.exe
- no trouble.
When I was working on this: https://forum.farmanager.com/viewtopic.php?f=3&t=10242
I tried many things and quickly realized that executing something involving a lot of quotes and backslashes via cmd.exe
is complete torture. The only way to get the exact command line was to run the process directly and obtain the command line via Windows-specific GetCommandLine() rather than using C-standard argc/argv. That's what bashcmd.exe
does. Only this way I was able to send the exact command line from Far to bash (bashcmd.sh
), with all the quotes, backslashes and such intact.
Is there a reason ConEmuC uses cmd.exe
rather than run the process directly? Besides this issue, there's also the inefficiency of spawning an extra process.
When I execute, for example, from Far's command line (outside of ConEmu of course)
C:\tools\7z.exe a -r test.7z *.*
Far always starts cmd.exe. But you insist it doesn't. What I'm doing wrong?
Just tried it, Far didn't use cmd.
I've digged deep in Far sources so I know what's happening in there. If you wanna see for yourself, see execute.cpp
. Far checks the command line (PartCmdLine()
) according to specified ComspecCondition
option, or default if none specified - by default it checks for presence of any of <>|&
characters not within quotes.
Your 7z
command line doesn't have any of those characters, therefore Far proceeds to directly execute 7z.exe
(see Execute()
function).
If Far finds the command line too complex (pipes, redirections etc.), it uses ComSpec to execute the command - either System.Executor.Comspec
(far:config option) if set, or ComSpec env var.
In my case, I've set System.Executor.Comspec
to %FAR_ComSpec%
which is an env var pointing to my bashcmd.exe
(all of these setup details described in the README of bashcmd 7z archive I've reference in a previous comment).
Some curious findings.
grep external_id video_ids.txt | cut -d\" -f4 | sort -u
- fails (intermediary cmd.exe
)
bashcmd.exe: cmdLine="C:\cygwin\usr\local\bin\bashcmd.exe" /S /C "grep external_id video_ids.txt | cut -d\" -f4
grep external_id video_ids.txt | cut -d\" -f4 | sort -u -cur_console
- fails (intermediary cmd.exe
)
bashcmd.exe: cmdLine="C:\cygwin\usr\local\bin\bashcmd.exe" /S /C "grep external_id video_ids.txt | cut -d\" -f4
grep external_id video_ids.txt | cut -d\" -f4 | sort -u -new_console
- runs in new console and works (no intermediary cmd.exe
)
bashcmd.exe: cmdLine="C:\cygwin\usr\local\bin\bashcmd.exe" /S /C "grep external_id video_ids.txt | cut -d\" -f4 | sort -u"
Also, if I run this command from a Cygwin bash under ConEmu, it executes correctly without any intermediary cmd.exe
.
# export BASHCMD_DEBUG=pause
# bashcmd.exe /S /C "grep external_id video_ids.txt | cut -d\" -f4 | sort -u"
bashcmd.exe: cmdLine=`C:\cygwin\usr\local\bin\bashcmd.exe /S /C "grep external_id video_ids.txt | cut -d\" -f4 | sort -u"`
So for some reason the issue only occurs when running under Far in current console.
P.S. It doesn't seem plausible to me that Far spawns this cmd.exe
, since in Far my Comspec is set to C:\cygwin\usr\local\bin\bashcmd.exe
. So I can only imagine ConEmuC is starting this cmd.exe
for some reason.
http://bugs.farmanager.com/view.php?id=3322
Versions
ConEmu build: 160914 x64 Far Manager build: 3.0.0.4805 x64 OS version: Windows 7 x64
Problem description
When executing this command from Far, the entire command line is passed correctly to the command interpreter.
grep external_id video_ids.txt | cut -d\" -f4
Command interpreter receives:"C:\cygwin\usr\local\bin\bashcmd.exe" /S /C "grep external_id video_ids.txt | cut -d\" -f4"
- as expected.Adding a pipe to the command results in incorrect (truncated, no trailing
"
character) command line passed to the command interpreter.grep external_id video_ids.txt | cut -d\" -f4 | sort -u
Command interpreter receives:"C:\cygwin\usr\local\bin\bashcmd.exe" /S /C "grep external_id video_ids.txt | cut -d\" -f4
- the| sort -u"
part is missing.