【问题标题】:Script using rvm ruby-2.1.2 but console using rvm jruby-1.7.12. Script failed脚本使用 rvm ruby​​-2.1.2,但控制台使用 rvm jruby-1.7.12。脚本失败
【发布时间】:2014-09-24 04:09:01
【问题描述】:

全部,

我认为在通过这里的问题进行侦察后,它没有被问到。这是我的问题:

我使用的是 Ubuntu 14.04。我开发了一个由 ruby​​-2.1.2 运行的脚本。我已经包括了 shebang 线

#!/usr/bin/env ruby

在脚本头中,脚本路径包含在 .profile 中。脚本通过 chmod +x 可执行。该脚本可以在任何地方执行,没​​有问题。我的 rvm -v 输出是

rvm 1.25.27 (stable) by Wayne E. Seguin, Michal Papis [https://rvm.io/]

但是今天我开始使用 jruby-1.7.12 进行开发,并且我已经从命令行运行了 jruby。突然,脚本不再工作了。该脚本现在使用 jruby-1.7.12 而不是 ruby​​-2.1.2 运行。这绝对不是我想要的。

第一次尝试

将shebang线改为

#!/usr/bin/env rvm ruby-2.1.2 do ruby 

shell 回复“/usr/bin/env: rvm ruby​​-2.1.2 do ruby​​: No such file or directory”

第二次尝试

通过将 shebang 线更改为

再次尝试
#!/home/xxx/.rvm/rubies/ruby-2.1.2/bin/ruby 

现在不是运行脚本,而是输出显示它正在为原生模块编译,在 jruby 环境下:

/home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:89:in `run': ERROR: Failed to build gem native extension. (Gem::Ext::BuildError)

/home/xxx/.rvm/rubies/ruby-2.1.2/bin/ruby extconf.rb
extconf.rb:4:in `<main>': Use RbConfig instead of obsolete and deprecated Config.
extconf.rb:4:in `<main>': Use RbConfig instead of obsolete and deprecated Config.
extconf.rb:5:in `<main>': Use RbConfig instead of obsolete and deprecated Config.
# These line gets substituted with the actual Config::CONFIG items location by extconf.rb
PREFIX = /home/xxx/.rvm/rubies/ruby-2.1.2
BINDIR = /home/xxx/.rvm/rubies/ruby-2.1.2/bin
INSTALLDIR = $(PREFIX)/lib/ruby/shared/rubygems/defaults
OLDINSTALLDIR = $(PREFIX)/lib/ruby/site_ruby/1.8/rubygems/defaults

ifeq (true,$(shell test -x $(BINDIR)/jruby && echo true))
RAKE=$(BINDIR)/jruby -S rake
else
RAKE=rake
endif

build: .build-post

.build-pre:

.build-post: .build-impl build-exe

build-exe:
    @if [ "$(findstring mingw, $(CONF))" ]; then                                            \
    ${MAKE} -f ${SUB_CONFMK} SUBPROJECTS=${SUBPROJECTS} jruby.exe jrubyw.exe;                   \
    if [ -d ../jruby ]; then cp jruby.exe jrubyw.exe jruby.dll ../jruby/bin/; fi;                   \
    if [ -d D:/work/jruby-dev/jruby ]; then cp jruby.exe jrubyw.exe jruby.dll D:/work/jruby-dev/jruby/bin/; fi; \
    fi

jruby.res: resources/jruby.rc
    windres $^ -O coff -o $@

jruby.exe: jrubyexe.cpp nbexecloader.h utilsfuncs.cpp utilsfuncswin.cpp jruby.res
    g++ $(CXXFLAGS) $^ -s -o $@ $(LDLIBSOPTIONS) -static

jrubyw.exe: jrubyexe.cpp nbexecloader.h utilsfuncs.cpp utilsfuncswin.cpp jruby.res
    g++ $(CXXFLAGS) -DJRUBYW -mwindows $^ -s -o $@ $(LDLIBSOPTIONS) -static

install:
    @if [ ! -f ./jruby ]; then echo "Please run 'make' first."; exit 1; fi
    @if [ x$(BINDIR) = xnotspecified/bin ]; then echo "Please define where to install by passing PREFIX=<jruby-home>."; exit 1; fi
    @if [ ! -w $(BINDIR) ]; then echo "'$(BINDIR)' does not exist or cannot write to '$(BINDIR)'."; exit 1; fi
    @if [ -f $(BINDIR)/jruby -a ! -w $(BINDIR)/jruby ]; then echo "Cannot write to '$(BINDIR)/jruby'."; exit 1; fi
    cp ./jruby $(BINDIR)/jruby
    @if [ x$(PREFIX) = xnotspecified ]; then echo "Please define where to install by passing PREFIX=<jruby-home>."; exit 1; fi
    @if [ ! -w $(INSTALLDIR) ]; then \
        if [ ! -w $(OLDINSTALLDIR) ]; then \
            echo "Neither '$(INSTALLDIR)' nor '$(OLDINSTALLDIR)' exist and are writable"; exit 1; \
        else \
            echo "cp ./lib/rubygems/defaults/jruby_native.rb $(OLDINSTALLDIR)"; \
            cp ./lib/rubygems/defaults/jruby_native.rb $(OLDINSTALLDIR); \
        fi; \
    else \
        echo "cp ./lib/rubygems/defaults/jruby_native.rb $(INSTALLDIR)"; \
        cp ./lib/rubygems/defaults/jruby_native.rb $(INSTALLDIR); \
    fi;

test:
    $(RAKE)

# Universal binary on OSX
FAT_ARCHES=i386 ppc x86_64

fat: $(FAT_ARCHES)
    lipo -create $(foreach arch,$(FAT_ARCHES),build/unix/Darwin-$(arch)/jruby-launcher) -output jruby
    $(RAKE)

$(FAT_ARCHES):
    $(MAKE) -f $(SUB_CONFMK) CND_PLATFORM=Darwin-$@ CFLAGS="-arch $@" build/unix/Darwin-$@/jruby-launcher

clean: .clean-post

.clean-pre:
    -rm -rf build/*

.clean-post: .clean-impl
    rm -f *.exe *.res

clobber: .clobber-post

.clobber-pre:

.clobber-post: .clobber-impl

all: .all-post

.all-pre:

.all-post: .all-impl

help: .help-post

.help-pre:

.help-post: .help-impl

# Use the manually-maintained inc/*.mk makefiles.
# Pass NETBEANS=true on the command-line to use NB's generated
# nbproject/*.mk

ifdef NETBEANS
SUB_IMPLMK=nbproject/Makefile-impl.mk
else
SUB_IMPLMK=inc/Makefile-impl.mk
SUB_CONFMK=inc/Makefile-rules.mk
endif

# include project implementation makefile
include $(SUB_IMPLMK)

# Pick conf based on OS. for mingw64, must manually override for now.
ifeq ($(OS),Windows_NT)
CONF=mingw
else
CONF=unix
endif

ifdef NETBEANS
SUB_CONFMK=nbproject/Makefile-${CONF}.mk
endif

make "DESTDIR=" clean
rm -rf build/*
make -f inc/Makefile-rules.mk CONF=unix SUBPROJECTS= .clean-conf
make[1]: Entering directory `/home/xxx/.rvm/rubies/jruby-1.7.12/lib/ruby/gems/shared/gems/jruby-launcher-1.1.0-java'
rm -f -r build/unix
rm -f -f jruby
make[1]: Leaving directory `/home/xxx/.rvm/rubies/jruby-1.7.12/lib/ruby/gems/shared/gems/jruby-launcher-1.1.0-java'
rm -f *.exe *.res

make "DESTDIR="
make -f inc/Makefile-rules.mk CONF=unix SUBPROJECTS= .build-conf
make[1]: Entering directory `/home/xxx/.rvm/rubies/jruby-1.7.12/lib/ruby/gems/shared/gems/jruby-launcher-1.1.0-java'
make -f inc/Makefile-rules.mk jruby
make[2]: Entering directory `/home/xxx/.rvm/rubies/jruby-1.7.12/lib/ruby/gems/shared/gems/jruby-launcher-1.1.0-java'
mkdir -p build/unix/Linux
rm -f build/unix/Linux/argparser.o.d
g++ -O2 -Wall    -c argparser.cpp -MMD -MP -MF build/unix/Linux/argparser.o.d -o build/unix/Linux/argparser.o
argparser.cpp: In member function ‘bool ArgParser::initPlatformDir()’:
argparser.cpp:134:40: warning: converting to non-pointer type ‘char’ from NULL [-Wconversion-null]
         char sep[2] = { FILE_SEP, NULL };
                                        ^
argparser.cpp:191:58: warning: ignoring return value of ‘char* getcwd(char*, size_t)’, declared with attribute warn_unused_result [-Wunused-result]
         getcwd(path, PATH_MAX - platformDir.length() - 1);
                                                          ^
mkdir -p build/unix/Linux
rm -f build/unix/Linux/utilsfuncs.o.d
g++ -O2 -Wall    -c utilsfuncs.cpp -MMD -MP -MF build/unix/Linux/utilsfuncs.o.d -o build/unix/Linux/utilsfuncs.o
utilsfuncs.cpp: In function ‘std::string findOnPath(const char*)’:
utilsfuncs.cpp:126:12: warning: unused variable ‘found’ [-Wunused-variable]
     char * found;
            ^
mkdir -p build/unix/Linux
rm -f build/unix/Linux/ng.o.d
gcc -O2 -Wall    -c ng.c -MMD -MP -MF build/unix/Linux/ng.o.d -o build/unix/Linux/ng.o
mkdir -p build/unix/Linux
rm -f build/unix/Linux/strlcpy.o.d
gcc -O2 -Wall    -c strlcpy.c -MMD -MP -MF build/unix/Linux/strlcpy.o.d -o build/unix/Linux/strlcpy.o
mkdir -p build/unix/Linux
rm -f build/unix/Linux/jrubyexe.o.d
g++ -O2 -Wall    -c jrubyexe.cpp -MMD -MP -MF build/unix/Linux/jrubyexe.o.d -o build/unix/Linux/jrubyexe.o
mkdir -p build/unix/Linux
rm -f build/unix/Linux/unixlauncher.o.d
g++ -O2 -Wall    -c unixlauncher.cpp -MMD -MP -MF build/unix/Linux/unixlauncher.o.d -o build/unix/Linux/unixlauncher.o
g++ -O2 -Wall     -o build/unix/Linux/jruby-launcher build/unix/Linux/argparser.o build/unix/Linux/utilsfuncs.o build/unix/Linux/ng.o build/unix/Linux/strlcpy.o build/unix/Linux/jrubyexe.o build/unix/Linux/unixlauncher.o -lstdc++
cp build/unix/Linux/jruby-launcher jruby
make[2]: Leaving directory `/home/xxx/.rvm/rubies/jruby-1.7.12/lib/ruby/gems/shared/gems/jruby-launcher-1.1.0-java'
make[1]: Leaving directory `/home/xxx/.rvm/rubies/jruby-1.7.12/lib/ruby/gems/shared/gems/jruby-launcher-1.1.0-java'

make "DESTDIR=" install
cp ./jruby /home/xxx/.rvm/rubies/ruby-2.1.2/bin/jruby
Neither '/home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/shared/rubygems/defaults' nor '/home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/1.8/rubygems/defaults' exist and are writable
make: *** [install] Error 1

make install failed, exit code 2

Gem files will remain installed in /home/xxx/.rvm/gems/jruby-1.7.12@global/gems/jruby-launcher-1.1.0-java for inspection.
Results logged to /home/xxx/.rvm/gems/jruby-1.7.12@global/extensions/x86_64-linux/2.1.0/jruby-launcher-1.1.0-java/gem_make.out
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:51:in `block in make'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:43:in `each'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:43:in `make'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/ext_conf_builder.rb:47:in `block in build'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/tempfile.rb:324:in `open'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/ext_conf_builder.rb:17:in `build'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:161:in `block (2 levels) in build_extension'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:160:in `chdir'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:160:in `block in build_extension'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:159:in `synchronize'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:159:in `build_extension'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:198:in `block in build_extensions'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:195:in `each'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/ext/builder.rb:195:in `build_extensions'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:1436:in `block in build_extensions'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/user_interaction.rb:45:in `use_ui'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:1434:in `build_extensions'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/stub_specification.rb:60:in `build_extensions'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/basic_specification.rb:56:in `contains_requirable_file?'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:925:in `block in find_inactive_by_path'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:924:in `each'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:924:in `find'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:924:in `find_inactive_by_path'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems.rb:185:in `try_activate'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:132:in `rescue in require'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:144:in `require'
    from /home/xxx/Tools/DogFood/TrackerClient/client/webservices.rb:2:in `<top (required)>'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /home/xxx/Tools/DogFood/TrackerClient/dvcs/git/git.rb:4:in `<top (required)>'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /home/xxx/Tools/DogFood/TrackerClient/dvcs/dvcs.rb:2:in `<top (required)>'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /home/xxx/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /home/xxx/Tools/DogFood/TrackerClient/tc2.rb:10:in `<main>'

我相信还有其他环境值需要更改,例如 GEM_PATH 和 RUBY_VERSION,如本网站其他帖子中所述。这不是首选。

第三次尝试

在 rvm 的 bin 文件夹中找到了一个名为 rvm-shebang-ruby 的实用程序。将shebang更改为

#!/usr/bin/env rvm-shebang-ruby

它不是运行脚本,而是执行 ruby​​ 并在控制台上等待。

请问我现在还有其他方法可以实现我想要的,那就是: 严格使用 ruby​​-2.1.2 和 ruby​​ 2.1.2 运行脚本位于 RVM 环境中。

谢谢!

【问题讨论】:

  • 不确定出了什么问题,在我的安装#!/usr/bin/env rvm jruby-1.7.11 do ruby 后跟puts JRUBY_VERSION 打印1.7.11,正如预期的那样。如果我把ruby-2.1.1RUBY_VERSION 改为,我会再次得到正确的2.1.1
  • 如果我用 ruby​​ 执行文件,是的,它可以工作。但是如果我使文件可执行并直接从命令行执行,不,它会失败。

标签: ruby linux rvm sh shebang


【解决方案1】:

好的,您的第一个示例(我认为这是正确的)适用于我的系统,因为我使用的是 OSX。显然,这不是可移植的语法。

啊,我明白了。我在 OSX 上,显然有 env 工作方式不同。来自Wikipedia on Shebang

另一个可移植性问题是命令参数的解释。包括 Linux 在内的一些系统不会拆分参数;[11] 例如,在运行脚本时,第一行类似,

#!/usr/bin/env python -c

也就是说,python -c 将作为一个参数传递给 /usr/bin/env,而不是两个参数。 Cygwin 也有这种行为。

你可以这样做:

#!/usr/bin/env ruby

unless RUBY_VERSION == '2.1.2'
  Process.exec('rvm', 'ruby-2.1.2', 'do', $0, *ARGV)
end

puts RUBY_VERSION

这当然会加载文件两次,并加载解释器两次。当文件第一次加载时,你的文件中也不能有任何语法破坏的东西,所以所有新的东西都应该卸载到一个需求中。而且我对此不太满意。

一个更好、更易读的想法是有一个 shell-script 包装器:

#!/bin/sh
rvm ruby-2.1.2 do script.rb

【讨论】:

  • 你的“更好的方法”是我最终要做的。不过,我仍然希望有另一种方法。似乎这是要走的路。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多