程序"execinput"从stdin读取输入行 并将它们存储到字符数组"缓冲区"中,然后执行以下操作:
system(buffer);
让"命令"是任何一组有效的程序、参数和 bash 语法。 理想情况下,接下来的两行将给出相同的结果(暂时忽略"命令"中任何双引号的处理):
command
echo "command" | execinput
在 bash shell 中运行的 Linux 系统上确实如此。 但是,在"Msys2 MingW 32bit"外壳中的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 用来分隔子命令的字符。 linux系统上的最后一个命令,无论是直接在bash中还是通过system()给出:
3
1
2
在 linux bash 环境中,所有命令都是一样的,无论是直接运行还是通过execinput()
中的system()
运行。在MSYS2环境中,他们没有。
我相信COMSPEC
和PATH
以某种方式参与其中,但将前者设置为这样:
export COMSPEC="C:progsmsys32usrbinbash.exe -c "
而不是默认的 COMSPEC 值:
C:Windowssystem32cmd.exe
结果仍然不一样。
有人可以解释一下这里发生了什么,并希望如何使"命令"直接在 bash 命令行上以及使用system()
调用时出现相同?
更多信息。 在 MSYS2 的 bash 命令行中:
echo 'set' | execinput > short.txt
echo 'bash -c "set"' | execinput > long.txt
然后比较文件内容。 主要区别在于:
- 长.txt有 11 个 BASH *符号加上 DIRSTACK, EUID, GROUPS, IFS, MACHTYPE, OPTERR, OPTIND, OSTYPE, PPID, SHELLOPTS,UID.
简而言之.txt没有这些。- SYSTEMROOT,COMSPEC,CONTITLE,HOMEPATH和许多其他人是 长引号.txt单引号,短引号.txt。
字符串在其他方面是相同的。- PWD在长篇上是完全linux/posix语法的.txt并且有它的根 在 MSYS2 文件系统的顶部。 PWD 采用混合语法 简而言之.txt(以 C: 开头,然后有一个/分隔的路径)并且 完整的窗口路径。
- PATH 长.txt以 linux/posix 语法条目开头, 根在 MSYS2 文件系统的顶部,然后是条目 比如/c/Windows/System32。 短.txt具有完整的条目 窗口语法。
- 长.txt SHLVL=2,短.txt SHLVL=1。
在你的问题中,你假设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的已定义路径。
"Msys2 MingW 32bit"意味着您打开一个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 下运行。