为什么perl vc.8.8(git-bash)中的perl exec()在v5.18.2(草莓)中的工作方式不同?

时间:2014-01-17 19:36:05

标签: git perl exec strawberry-perl

最近将Strawberry Perl放在Windows 8.1计算机上,发现exec /bin/perl的git-bash中的v5.8.8与/c/strawberry/perl/bin/perl的草莓的行为不同。这是我发现的非常简单的脚本(纯粹是在玩$PATH时出乎意料):

#!/usr/bin/env perl
my $comment = "@ARGV" || 'update';
exec "git status; git add -A . ; git status; git commit -m '$comment'; git push";

这适用于git-bash/bin/perl),但如果在/c/strawberry/perl/bin/perl中找到$PATH,则会发生以下错误:

git: 'status;' is not a git command. See 'git --help'.

Did you mean this?
    status

两种情况下的代码都相同。我的预感是,草莓中的perl 5.18已经改变了exec命令本身的行为,因为它在上下文中解释了它的参数(就像perl喜欢这样做),它总是相当复杂。

我主要担心的是,perl的两个版本在某种程度上使这个相当简单的代码在perl版本之间不兼容,而不是其他一些简单的系统配置问题,甚至可能是草莓发行版本身而不是perl的问题。

如果这是一个perl兼容性问题,我倾向于坚持使用v5.8.8,它完成了我想要Perl为我做的所有事情(在转到另一种语言之前)。

exec perl语句是否在这些版本之间发生了变化?我在互联网上找不到它的证据。

要重新创建此行为:

在Windows机器上安装git-scm.org:

  • 下载并安装http://git-scm.org
  • 启动git-bash shell
  • 创建一个shell脚本并将上面的代码放入其中
  • 使用chmod 755
  • 设置执行权限
  • 确保您使用带有which perl
  • 的/ bin / perl
  • 执行脚本

然后......

  • 安装Strawberry Perl
  • 在其他所有内容之前将$ PATH设置为包括/ c / strawberry / perl / bin
  • 使用which perl
  • 进行检查
  • 执行相同的脚本

这是了解正在发生的事情以及差异为何重要的最佳方式。这意味着为git-bash(v5.8.8)编写的标准perl脚本不适用于草莓中的5.18。我的下一步是在Linux机器上安装perl 5.18并确保其行为与5.8.8相同。如果有人已经这样做了,请告诉我。

注意:在我喜欢的情况下,使用其他操作系统不是一种选择,因为我们在需要Windows的同一台机器上进行其他游戏开发。

注意:我使用Perl代替Bash,因为我的小黑客往往会成长。我使用Perl代替Python或Node,或者因为Perl标配git-bash,因此我不需要在每台学生机器上安装另一个。我只把草莓放在那里因为我想要添加perlpod剥离的git-bash功能。

对那些投票问题的人。您只是证明为什么stackexchange是一个很难找到准确信息和真正帮助的借口。感谢您验证我决定回到真正的专家所在的IRC,而不是那些为人气竞赛而游行的人。

1 个答案:

答案 0 :(得分:6)

这不是关于你的Perl版本,而是关于bash与Windows命令shell的关系。任何版本的Strawberry Perl都可以通过execsystemqx等调用以及perl附带的git-bash来调用Windows命令shell显然配置为调用Unix仿真环境。为Cygwin构建的Perl是在Windows上运行但是将外部命令发送到Unix仿真环境的另一个解释器示例。

Windows命令shell无法识别;字符以终止/分离命令,例如sh,因此您无法在Strawberry Perl上使用exec运行一系列命令就像你在git-bash perl上一样。

解决方法:

  1. Windows确实对待(AFAICT)像bash这样的&&字符 - 您可以使用它是一个命令分隔符,只要命令成功就会继续执行命令

    exec "git status && git add -A . && git status && git commit -m '$comment' && git push"
    
  2. 将命令列表放入批处理文件中,并在批处理文件名上调用exec

  3. 使用system(返回)将命令分成多个调用,用于除最后一个之外的所有调用。

    system("git status");
    system("git add -A .");
    system("git status");
    system("git commit -m '$comment'");
    exec("git push");