Система mingw64 («команда») не совпадает с «командой» в оболочке - PullRequest
2 голосов
/ 14 мая 2019

Программа "execinput" считывает входные строки из стандартного ввода и сохраняет их в массив символов "буфер", а затем делает это:

system(buffer);

Пусть "команда" будет любым допустимым набором программ, параметров,и синтаксис bash.В идеале следующие две строки дадут один и тот же результат (на данный момент игнорируя обработку любых двойных кавычек внутри «команды»):

command
echo "command" | execinput

Это действительно так в системе linux, работающей в оболочке bash,Однако в bash в оболочке «Msys2 MingW 32bit» это происходит (конечная точка с запятой после 3 является преднамеренной):

echo 1; echo 2; echo 3;
1
2
3
echo "echo 1; echo 2; echo 3;" | execinput
1 ; echo 2; echo 3;
echo "echo 1 & echo 2 & echo 3;" | execinput
1
2
3;

Символ «&» - это то, что cmd.exe использует для разделения подкоманд.Эта последняя команда в системе Linux, либо непосредственно в bash, либо через system (), дает:

3
1
2

В среде Linux-bash все команды выполняются одинаково, независимо от того, выполняются ли они напрямую или через system() вexecinput().В среде MSYS2 они этого не делают.

Я считаю, что COMSPEC и PATH как-то участвуют, но установив первое так:

 export COMSPEC="C:\progs\msys32\usr\bin\bash.exe -c "

вместо COMSPEC по умолчаниюзначение:

C:\Windows\system32\cmd.exe

результаты все равно были не такими.

Может кто-нибудь объяснить, что здесь происходит, и, как мы надеемся, как заставить "команду" выдавать то же самое непосредственно в командной строке bash и когда вызывается с system()?


Подробнее.В командной строке bash в MSYS2:

echo 'set' | execinput > short.txt
echo 'bash -c "set"' | execinput > long.txt

затем сравните содержимое файла.ключевые различия:

  1. long.txt имеет 11 символов BASH * плюс DIRSTACK, EUID, ГРУППЫ, IFS, MACHTYPE, OPTERR, OPTIND, OSTYPE, PPID, SHELLOPTS, UID.
    Short.txt не имеет их.
  2. SYSTEMROOT, COMSPEC, CONTITLE, HOMEPATH и многие другие в одинарных кавычках в long.txt, в short.txt нет кавычек.
    В остальном строки одинаковые.
  3. PWD полностью в синтаксисе linux / posix в long.txt и имеет корень в верхней части файловой системы MSYS2.PWD имеет гибридный синтаксис в short.txt (начинается с C: затем имеет путь / разделенный /) и является полным путем Windows.
  4. PATH в long.txt начинается с записей синтаксиса linux / posix, root - вв верхней части файловой системы MSYS2, затем следуют записи, такие как / c / Windows / System32.Short.txt содержит записи, которые имеют полный синтаксис Windows.
  5. Long.txt имеет SHLVL = 2, short.txt имеет SHLVL = 1.

Ответы [ 2 ]

0 голосов
/ 14 мая 2019

«Msys2 MingW 32bit» означает, что вы открываете оболочку MSYS2 Bash, в которой задан путь, так что gcc разрешается в сборку mingw-w64, ориентированную на собственный Win32. Собственный исполняемый файл Win32 не имеет ничего общего с MSYS2 Bash; Командный процессор - cmd.exe. Оболочка MSYS2 - это всего лишь инструмент разработки.

Если вы откроете «Msys2 MSYS2», то gcc преобразуется в сборку mingw-w64, предназначенную для системы MSYS2. Вы можете проверить цель с помощью gcc -v, и она скажет Target: x86_64-pc-msys или подобное. Я проверил это, и он использовал /usr/bin/bash как командный процессор, как и ожидалось.

Обратите внимание, что разные цели используют разные установки gcc; цель MSYS2 - pacman -S msys2/gcc, а собственная цель Win32 - pacman -S mingw32/mingw-w64-i686-gcc. Он не использует ни одного компилятора, который выбирает цель с помощью переключателя, как некоторые сборки gcc.

Конечно, если вы создаете таргетинг на MSYS2, то полученный исполняемый файл должен быть запущен под MSYS2.

0 голосов
/ 14 мая 2019

В вашем вопросе вы предполагаете, что command означает "синтаксис Bash".

Однако, вызов system() вызывает sh на вашем Gnu / Linux и cmd.exe на вашем Windowsсистема.Интерпретация разными оболочками приводит к разным результатам двух командных строк, переданных в вызов system():

echo 1; echo 2; echo 3;
echo 1 & echo 2 & echo 3;

Я не знаю, есть ли способ заставить system() вызвать другую командупроцессор в Windows, если COMPSPEC, кажется, не влияет на него.

Если у вас есть контроль над исходным кодом execinput, я бы предложил реализовать там более переносимое выполнение command, например, используяодин из системных вызовов exec*() вместе с определенным путем к желаемой оболочке.

...