executing shell command from ruby - ruby

This isn't working in ruby and I don't understand why?
#!/usr/bin/env ruby
exec "sort data.txt > data.sort"
data.txt is a comma sepparated file. Anyway.. If I try to execute that line in the shell it works without a problem.
When I try to run this script from my script, I get an empty file.

This isn't really an answer, but I wanted to share that your original usage of exec is actually working for me. This was how I set it up.
data.txt
"1,2,3,4,5,6,7,8"
sort.rb (I don't know what your sort did so I am just writing the same data out)
File.open(ARGV[0]){|f| puts f.read}
irb session
irb(main):001:0> exec "sort data.txt > data.sort"
When I ran this in irb, I did get a data.sort output file and it contained "1,2,3,4,5,6,7,8" as expected. I can run the same exec line through irb or from another ruby file, and I get the output file with data each time.
I am running Ruby 1.8.6 on a 32bit Windows XP system.

Have you tried
%x(sort data.txt > data.sort)

Related

Permission Denied when passing files to a ruby program

I have a ruby program that accepts files as input. I am trying to test that this functionality works by piping a file into the program by entering
cat file1.txt | ./app.rb
However, when I do this I get -bash: ./app.rb: Permission denied
I have tried using sudo cat file1.txt | ./app.rb which prompts me for my password and then it appears nothing happens.
This works fine when I instead type
ruby app.rb file1.txt
Does anyone have any tips for how to get this to work?
As pointed out in the comments, I need to be able to read a file path from stdin AND pass them as parameters:
In my code I have this:
def input
if ARGV.length.positive?
ARGV
else
gets.chomp.split(' ')
end
end
I expect input to return an array of file paths.
As mentioned in the comments above, sending the contents of a file as STDIN to a program and passing the filename as a parameter are two very different things.
I cannot say which, if either, is "right" or "wrong" without knowing more context of what it is you're actually trying to achieve, but it's important to recognise the difference.
Now, the actual cause of the error here is that you're trying to execute the ruby file directly. You can fix this by running ruby on the filename instead:
cat file1.txt | ruby app.rb
It is possible to execute the file without writing ruby, but you must first make it executable:
chmod +x app.rb
And also write a Shebang at the top of the file, to specify that it should be executed as a ruby script, not a bash script (which is the default):
#!/usr/bin/env ruby

Ruby only executing the first line?

I'm writing a ruby script and found this strange behaviour.
Using ruby 2.4.2 [x86_64-darwin16]
Basically I'm trying to echo two separated messages and in my index.rb file I got:
exec("echo 'teste'")
exec("echo 'teste2'")
But when I run ruby ./index.rb
The output is:
teste
Why that's happening?
Shouldn't this be the output?
testeteste2
exec([env,] command... [,options])
Replaces the current process by running the given external command docs
It means that the first call to exec replaces your ruby program with echo, so the rest of the ruby program is not executed.
You can use backticks to run a command like you want:
`echo 'teste'`
`echo 'teste2'`

how to build wrapper script

Sort of an odd question, but: how would one go about creating a wrapper shell script that can be used in the #! line in other scripts.
wrap.sh
#!/bin/bash
set -e
echo "wrapper!"
exec ruby "$#"
test.rb
#!/usr/bin/env wrap.sh
puts RUBY_VERSION
puts "the ducks come from the trucks"
wrap.sh is in the path, and test.rb is marked as executable.
Now I do:
./test.rb
wrapper!
ruby: no Ruby script found in input (LoadError)
The goal is to execute the ruby script via the wrapper (The ruby version can be either local or comes from a traveling ruby install that is shipped along with the app).
As far as I can tell ruby is invoked, it's just unhappy with the #! in the test.rb and refuses to run the script. I cannot remove the #! because that's how the script is executed in the first place.
Any workarounds for this?
So, I cannot use rbenv/rvm/etc. There is more logic in the wrapper than this, but this is the gist of it.
Looks to me like the arguments are not being passed to Ruby in "$#". I don't think the bang-hash line is the problem.
I don't see anything in your script which actually passes the contents of test.rb to wrapper.sh, which is the bigger issue.
Perhaps the real problem can be solved by some other means? For example, is the problem you're trying to solve to run arbitrary commands prior to the invocation of any Ruby script from the command line? Perhaps it can be approached that way...
It looks like Ruby just checks that the hash-bang line contains "ruby": https://github.com/ruby/ruby/blob/v2_2_2/ruby.c#L1580 So basically having ruby somewhere in the #! line is all it takes.

Get newline in terminal after execution of Ruby scripts

I have an extremely simple hello.rb file containing only:
print 'Hello world!'
I then try to run this file from my Ubuntu 14 terminal using:
ruby hello.rb
However, this ends up looking just about like this:
user#machine:~/Documents/Ruby/HelloWorld$ ruby hello.rb
Hello world!user#machine:~/Documents/Ruby/HelloWorld$
I guess that's technically correct, but it would be more readable if a newline is inserted after the output Ruby's execution. For regular terminal commands such as dir this newline is inserted, and the prompt starts on a new line.In other words, I'd like to see this:
user#machine:~/Documents/Ruby/HelloWorld$ ruby hello.rb
Hello world!
user#machine:~/Documents/Ruby/HelloWorld$
What do I need to change to get this behavior? Do I need to change the way I call Ruby? Or should I change my terminal settings?
Use puts instead of print. It adds the newline.

echo back every Ruby code line like sh -x?

Is there a way to have a ruby script echo back (or log to file I can tail -f) every line executed, similar to bash -x or #echo on in DOS?
ruby -w doesn't do it--only increases verbosity of warnings etc.
Researched Unroller but it doesn't work, possibly too dated. Uncompilable dependencies.
I use irb a lot but in this case I need something non-interactive eg. to inspect post-mortem.
You can use
ruby -rtracer [your_script.rb]
There is also ruby-debug which can do
rdebug --trace [your_script.rb]
IRB does the trick:
irb script.rb

Resources