程序“ 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环境中却没有。
我相信COMSPEC
和PATH
参与其中,但是前者的设置如下:
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
然后比较文件内容。主要区别在于:
- long.txt具有11个BASH *符号以及DIRSTACK,EUID,GROUP, IFS,MACHTYPE,OPTERR,OPTIND,OSTYPE,PPID,SHELLOPTS,UID。
Short.txt没有这些。- SYSTEMROOT,COMSPEC,CONTITLE,HOMEPATH和许多其他文件 long.txt中的单引号,short.txt中的单引号。
字符串相同。- PWD在long.txt中采用完全linux / posix语法,其根目录 在MSYS2文件系统的顶部。 PWD采用混合语法 in short.txt(以C开头:然后具有/分隔路径),并且是 完整的Windows路径。
long.txt中的- PATH以linux / posix语法条目开头, 在MSYS2文件系统顶部的根目录,然后是条目 像/ c / Windows / System32。 Short.txt包含完整的条目 Windows语法。
- Long.txt的SHLVL = 2,short.txt的SHLVL = 1。
答案 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下运行。