mingw64 system(“ command”)与shell中的“ command”不同

时间:2019-05-13 23:06:27

标签: c windows bash mingw-w64 msys

程序“ execinput”从stdin读取输入行 并将它们存储到字符数组“缓冲区”中,然后执行以下操作:

system(buffer);

让“命令”是程序,参数和bash语法的任何有效集合。理想情况下,下两行给出的结果相同(暂时忽略“命令”中任何双引号的处理):

command
echo "command" | execinput

在bash shell中运行的linux系统上确实是这种情况。但是,在“ Msys2 MingW 32位”外壳中的bash中,会发生这种情况(故意在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用于分隔子命令的字符是“&”字符。直接在bash中或通过system()在linux系统上的最后一个命令给出:

3
1
2

在linux bash环境中,无论直接运行还是通过system()中的execinput()运行,所有命令都相同。在MSYS2环境中却没有。

我相信COMSPECPATH参与其中,但是前者的设置如下:

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

代替默认的COMSPEC值:

C:\Windows\system32\cmd.exe

结果仍然不同。

有人可以解释一下这里发生了什么吗,希望如何使bash命令行上的“命令”直接出现以及如何用system()调用时出现?


更多信息。在MSYS2的bash命令行中:

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

然后比较文件内容。主要区别在于:

  
      
  1. long.txt具有11个BASH *符号以及DIRSTACK,EUID,GROUP,   IFS,MACHTYPE,OPTERR,OPTIND,OSTYPE,PPID,SHELLOPTS,UID。
      Short.txt没有这些。
  2.   
  3. SYSTEMROOT,COMSPEC,CONTITLE,HOMEPATH和许多其他文件   long.txt中的单引号,short.txt中的单引号。
      字符串相同。
  4.   
  5. PWD在long.txt中采用完全linux / posix语法,其根目录   在MSYS2文件系统的顶部。 PWD采用混合语法   in short.txt(以C开头:然后具有/分隔路径),并且是   完整的Windows路径。
  6.   long.txt中的
  7. PATH以linux / posix语法条目开头,   在MSYS2文件系统顶部的根目录,然后是条目   像/ c / Windows / System32。 Short.txt包含完整的条目   Windows语法。
  8.   
  9. Long.txt的SHLVL = 2,short.txt的SHLVL = 1。
  10.   

2 个答案:

答案 0 :(得分:0)

在您的问题中,您假设command代表“ Bash语法”。

但是,system()调用是在Gnu / Linux上调用sh,而在Windows系统上是cmd.exe。由不同的shell解释会导致传递给system()调用的两个命令行的结果不同:

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

我不知道是否有任何方法可以使system()在Windows上不调用COMPSPEC来调用其他命令处理器。

如果您对execinput的源代码有控制权,我建议在此实现command的更可移植的执行,例如使用exec*()系统调用之一以及到所需shell的定义路径。

答案 1 :(得分:0)

“ Msys2 MingW 32位”意味着您打开MSYS2 Bash shell,并在其中设置路径,以便gcc解析为针对本机Win32的mingw-w64构建。本机Win32可执行文件与MSYS2 Bash无关。命令处理器为cmd.exe。 MSYS2 shell只是一个开发工具。

如果打开“ Msys2 MSYS2”,那么gcc将解析为针对MSYS2系统的mingw-w64构建。您可以使用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下运行。