I have written myself a simple Ruby script that requires the Listen Gem. Running it in the console like this works perfectly.
$ ruby script.rb ARGS
I was always passing the PWD as a argument. I got annoyed of that so I wanted to make the script executable across my linux. So I added the following line to the beginning of my script
#!/usr/bin/env ruby
require "listen"
...
When I now use it as a self executing file, it runs into an error.
$ ./script.rb
Output:
./listen.rb:55: uninitialized constant Listen (NameError)
from ./script.rb:3:in `require'
from ./script.rb:3
Do you have any suggestions what the cause of this problem could be? I have one guess: #!/usr/bin/env ruby calls a different ruby env that $ ruby actually is. But how can I find that out? (I am using rbenv to manage my rubys)
Related
I would like to write a CLI application wrapped into a Gem that can be invoked the same way git commands are invoked, or gem commands. Eg when running say "git clone " you don't need to precede it with 'ruby'. However, the tutorials and articles I've seen so far about writing gems, don't show this. The examples either require you to run your gem through irb, with appropriate requires, or you run it like 'ruby '. This is not what I want. If you know of any tutorials that cover this, then that would be great.
Thanks.
The "#!" line at the start of a script tells your shell which executable to execute the script with. In this case, it tells it to find the Ruby executable from the environment and give the script to it for execution.
By means of example, I have a file called "hi", with the following:
#!/usr/bin/env ruby
puts "hi!"
I make it executable:
$ chmod a+x hi
Then I can execute it directly, without explicitly invoking the Ruby interpreter:
$ ./hi
hi!
Per the tutuorial you would simply provide such a file which requires your gem and whatnot, and provide it in the executables property of your gemspec:
Gem::Specification.new do |s|
# ...
s.executables << 'hi'
When the gem is installed, the hi script would be installed into a location discoverable on the path, so you could then invoke it.
I am using Mac OS X. I have two versions (2.1.5 and 2.0.0) of Ruby installed. The former installed at /another/.path/to/ruby (there is a dot before "path" to mimic the fact that the path contains a dot-headed directory in between), in addition to the default system one (version 2.0.0) at /usr/bin/ruby. I used rbenv to install Ruby.
After I manually set the PATH environment variable so the default ruby command will be found in another directory: /another/.path/to/ruby. Now I check
which -a ruby
It is using correct ruby first, as output.
/another/.path/to/ruby
/usr/bin/ruby
Now I create a script, rbs, with the first line of shebang specifying the ruby to use.
#!/usr/bin/env ruby
puts 'hey there'
Then I run
./rbs
it outputs 'hey there'. Good. Meanwhile, the Ruby is using the correct version.
/usr/bin/env ruby --version
as well as
ruby --version
both output 2.1.5. So it does great job to use the new version.
However, here is where the problem occurs: now I update rbs file to be:
#!/another/.path/to/ruby
puts 'hey there'
Note that I updated the shebang to use the absolute path to the desired ruby. then I run
./rbs
It outputs:
./rbs: line 2: puts: command not found
which is too weird;
but if I run
ruby ./rbs
it outputs 'hey there' as normal. It looks like the shebang works perfect using /usr/bin/env ruby, but not for absolute path for the newly install ruby?
Why is this? Is there a way to fix it so the updated script can still work by typing the following?
./rbs
Thanks!
The puts: command not found message indicates that your script is not being run by Ruby, but by the shell instead. So first, I would double-check your shebang line's syntax and path.
Second, note that rbenv uses shims that dynamically find and run the right version of ruby (and associated programs like gem, etc). But the shims are scripts, and scripts can't themselves be shebang interpreters; you have to find and use the actual path to the ruby executable (as output by rbenv which ruby).
On the other hand, since /usr/bin/env is an executable, you can always use something like #!/usr/bin/env ruby, which will work even if the ruby it finds in the path is itself a script.
I can't comment, (otherwise I'd add as a comment) but I think its worthwhile to add that the
#!/usr/bin/env ruby
MUST be the first line of the file. This tripped me up for a while.
source
I'm pretty inexperienced with terminal type stuff besides the most basic commands, I recently switched from Bash to ZSH with in oh-my-zsh. I'm trying to make an executable ruby script at usr/bin/test.rb. For what it's worth, I never tried this with bash so I have no idea if its zsh specific.
$~ test.rb
/usr/bin/test.rb: line 2: puts: command not found
$~ ruby test.rb
ruby: No such file or directory -- test.rb (LoadError)
and my .zshrc file:
export ZSH=$HOME/.oh-my-zsh
source $ZSH/oh-my-zsh.sh
export PATH="/Users/jason/.rvm/gems/ruby-2.0.0-p247/bin:/Users/jason/.rvm/gems/ruby- 2.0.0-p247#global/bin:/Users/jason/.rvm/rubies/ruby-2.0.0-p247/bin:/Users/jason/.rvm/bin:.git/safe/../../bin:.git/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin:/Users/jason/.rvm/bin"
.
~ which ruby
/Users/jason/.rvm/rubies/ruby-2.0.0-p247/bin/ruby
test.rb
#!/usr/bin/env ruby
puts 'test!'
$~ test.rb
/usr/bin/test.rb: line 2: puts: command not found
This is probably because your script is missing an essential line, often called a "pound-bang line" or, more simply, a "bang line", which tells the operating system what program to use to execute the rest of the file. Typically, for Ruby scripts, it looks like:
#!/usr/bin/ruby
or
#!/usr/bin/env ruby
and MUST be the first line in the file. When the OS opens the file, it looks for #! and, if it sees those, launches the executable at the path given, and passes the script to it. That's basic script execution on a *nix system, and applies to sh/Bash/Perl/Python/Ruby and any number of other executable applications on a *nix system.
ruby test.rb
ruby: No such file or directory -- test.rb (LoadError)
I suspect the second failed because you weren't in the /usr/bin/ directory when you executed that command. Ruby tried to run the script but couldn't find it in the local/current directory.
I'm not trying to be cruel, but, as a programmer, you'll spend a huge amount of time at the command-line, especially so if you are programming in C/C++, Perl, Ruby, Python, or any non-IDE based language. You have to learn how the OS works otherwise disasters of varying sizes and shapes await you, so, in parallel to learning a language you need to learn how to use, and administer, your OS. You don't have to be a power-user or administrator, but you have to know enough to understand good instructions from ones that don't apply, or are just plain-wrong.
Well I was facing the same problem, I had ruby & rails installed but I couldn't run them on ZSH
The answer is so simple
Just Add the following lines to .zshrc
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
Then run
source ~/.zshrc
After that to check if ruby & rails are found by ZSH run
ruby --version
rails --verison
I need to run a few lines of Ruby code from terminal, but I can't find the needed parameter for it.
Can you explain how to do this?
If Ruby is installed, then
ruby yourfile.rb
where yourfile.rb is the file containing the ruby code.
Or
irb
to start the interactive Ruby environment, where you can type lines of code and see the results immediately.
You can run ruby commands in one line with the -e flag:
ruby -e "puts 'hi'"
Check the man page for more information.
I have the following 2 regular expressions in a ruby file. They run fine when i use the ruby command but if i try to run via ./apachereport.rb it generates an error.
regex:
urls = parse(#file, /(?<=GET )\S+/)
codes = parse(#file, /(?<=HTTP\/[0-9]\.[0-9]" )\S+/)
error:
./apachereport.rb:34: undefined (?...) sequence: /(?<=GET )\S+/
./apachereport.rb:47: undefined (?...) sequence: /(?<=HTTP\/[0-9]\.[0-9]" )\S+/
The shebang I'm using is as follows, which seems to work fine with other ruby files:
#!/usr/bin/ruby
The most likely explanation for this is that you have multiple versions of ruby installed. The version installed in /usr/bin (which is the one you're using in your shebang line) is 1.8.X, which did not support ?<= (look-behind) in regexen. The one you execute when you type ruby apachereport is probably ruby 1.9, which does support ?<=.
To verify that this is the case type in which ruby and notice that it prints something other than /usr/bin/ruby and/or compare the results of /usr/bin/ruby --version to ruby --version.