我正在尝试下载我通过bundle install
下载的几个示例rails项目中列出的ruby gem,其中包含通过RVM安装的最新版本的ruby,我按照here的说明正确下载捆绑文件中列出的宝石。我以为我会用这个perl脚本加快这个过程:(对bash不太满意):
#!/usr/bin/perl
use File::Copy qq(copy);
use strict;
use warnings;
my @files = `ls`;
foreach my $dir (@files)
{
chomp $dir;
if( -d $dir)
{
print "\n\n\tabout to enter $dir\n\n\n";
print `cd "$dir"`;
system("echo \"2.2.0\" > .ruby-version");
system("echo \"$dir\" > .ruby-gemset");
copy("Gemfile", "tmp.save") or die "copy: $!\n";
open(RD,"<tmp.save") or die "$dir: tmp.save: $!\n";
open(WR,">Gemfile") or die "$dir: Gemfile: $!\n";
print WR <RD>;
print WR "\n";
print WR "ruby \'2.2.0\'";
print WR "\n\n";
while(<RD>) { print WR $_; print WR "\n"; }
close(RD); close(WR);
print `cd ..`;
print `cd "$dir"`;
print `bundle install`;
print `cd ..`;
}
}
错误是:
copy: No such file or directory
该文件显然存在这些项目可能是使用rails <name>
命令创建的。为什么会发生这种情况?如何解决?
答案 0 :(得分:4)
当您使用system
或反引号调用外部命令时,会生成一个新进程。该进程获得自己的环境,不与父进程或其他子进程共享:
system('pwd'); # /foo
system('cd "/bar"');
system('pwd'); # still /foo
(请注意,如果您实际上并未存储命令的输出,则最好使用system
而不是反引号。)
这意味着当您`cd "$dir"`
时,您的Perl脚本的工作目录不会更改。要修复,请使用本机Perl命令,而不是调用shell命令。
这是一个粗略的例子(未经测试):
use strict;
use warnings;
use File::Copy;
my $parent_dir = 'foo';
opendir my $dh, $parent_dir or die "opendir failed on '$parent_dir': $!";
my @subdirs = map { "$parent_dir/$_" }
grep { $_ !~ /^\.\.?$/ && -d "$parent_dir/$_" } readdir $dh;
foreach my $subdir (@subdirs) {
my $source = "$subdir/Gemfile";
my $target = "$subdir/tmp.save";
if (-f $source) {
copy $source, $target or die "copy failed: $!";
}
}