ruby executing remote scripts in one line. (like installing rvm) - ruby

install rvm in one line example:
user$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
Now, say I have a ruby scripts like this at http://blah.com/helloworld.rb
puts "what's ur name?"
name = gets.chomp
puts "hello world from web, #{name}"
I would like to achieve this it in my shell without creating a temp file in one line or even better one command.
wget http://blah.com/helloworld.rb; ruby helloworld.rb; rm helloworld.rb
I have tried this, but user prompt will be ignored because of earlier pipe.
curl -s http://blah.com/helloworld.rb | ruby
What's the correct way to executing a remote ruby script? Thanks!

Like this:
ruby < <(curl -s http://blah.com/helloworld.rb)
Ruby evaluates ruby code similarly to how bash evaluates shell code

Another Ruby option based on Calibre install for shell scripts:
ruby -e "require 'open-uri'; system open('http:// or local file').read"
The same for Ruby scripts:
ruby -e "require 'open-uri'; eval open('http:// or local file').read"
Edited: Fixed missing quote and added Ruby script execution

From http://brew.sh/:
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"

In your Ruby code, you have to reopen stdin and tie it to the controlling terminal device /dev/tty!
rubyscript="$( cat <<-'EOF'
puts "what's ur name?"
name = gets.chomp
puts "hello world from web, #{name}"
EOF
)"
ruby <(echo '$stdin.reopen(File.open("/dev/tty", "r"))'; echo "$rubyscript")

Related

Ruby shell script read from XCode plist

I am trying to read a plist value using a /usr/bin/ruby script. How can I do this?
Bugsnag API script
fork do
Process.setsid
STDIN.reopen("/dev/null")
STDOUT.reopen("/dev/null", "a")
STDERR.reopen("/dev/null", "a")
require 'shellwords'
BUGSNAG_API_KEY=$(defaults read "$FRAMEWORK/APIKeys.plist" bugsnag) // Convert this to ruby
Dir["#{ENV["DWARF_DSYM_FOLDER_PATH"]}/*/Contents/Resources/DWARF/*"].each do |dsym|
system("curl --http1.1 -F apiKey={BUGSNAG_API_KEY} -F dsym=##{Shellwords.escape(dsym)} -F projectRoot=#{Shellwords.escape(ENV["PROJECT_DIR"])} https://upload.bugsnag.com/")
end
end
BUGSNAG_API_KEY=$(defaults read "$FRAMEWORK/APIKeys.plist" bugsnag)
Assuming this is sh, it's running a command and capturing its output in a string. In Ruby you use backticks to do that
BUGSNAG_API_KEY = `defaults read #{ENV['FRAMEWORK']}/APIKeys.plist bugsnag`
The only thing I had to change was using ENV to access environment variables instead of sh's $ syntax.

How to use 'ruby -e' to execute multiline program?

I want to execute program by 'ruby -e' but it executes program if it's in single line but it's not executing if it's multiple line and throws the error. For an example,
>ruby -e "puts 'rajagopalan'"
=>rajagopalan
but
>ruby -e "a=[1,2,3,4,5]
a.each do |i|
puts i
end
"
it throws the error that "a.each do |i|
The syntax of the command is incorrect.
"
Can someone guide me how to execute the mulitiline via ruby -e
I have attached image here
you can try here document in your shell command:
ruby <<END
a=[1,2,3,4,5]
a.each do |i|
puts i
end
END
Hope this helps....
Try this:
>ruby -e "a=[1,2,3,4,5]; a.each do |i| puts i; end"
Basic idea, use a semi-colon wherever a new-line would be needed.
This has nothing to do with Ruby. You need to read the manual of your terminal emulator and your shell and figure out how to escape newlines.
As can be seen in the error you posted, you get a shell prompt after the first line, so the shell clearly seems to think the command is finished. Ergo, the shell tries to interpret the Ruby commands as shell commands, which leads to the error.

Access environment variable in IRB but not when running file

require 'io/console'
def test
IO.console.winsize
end
puts "1: test: #{test()}"
puts "2: env: #{ENV['COLUMNS']}"
When I run this, this is what I see in my console:
1: test: [23, 80]
2: env:
In other words, I'm not able to print out ENV['COLUMNS'] when I run the program
However, typing ENV['COLUMNS'] within IRB gives me a string equal to the terminal width.
I am wondering why this is the case.
Only variables that are exported by your shell will be available in a Ruby script:
$ ruby -e "puts ENV['COLUMNS']"
$ export COLUMNS
$ ruby -e "puts ENV['COLUMNS']"
80
this answer here presents a possible workaround (follow the first link and check out the yaml branch on Github)
here is an answer that presents a way to get the terminal size without using shell variables

Ruby thor command line tool commands

I am planning on making my first command line tool and was wondering about how the naming and commands work.
I would like my tool to function similarly to Git, in the sense that you just install it, then to run commands you just enter git clone or git commit. In many of the examples I have seen the tools are something like thor foo:bar or ./foo.rb bar.
My main question is how can I make it so if my tools name is Foo, and the command in my tool is bar, all the user has to do is run Foo bar in the command line.
In the case of git clone the way it works is that git program is executed and clone is passed to it as a parameter. So, if you have several scripts that should be started in a similar manner, you can create a small launcher. This code is in bash(but the script is sh compatible, so you can safely change the shebang to /bin/sh). It is very easy to write the same thing in any other language.
#!/bin/bash
command=$1
shift
case $1 in
cmd1)
echo "Executing command #1"
./smallcmd1 "$#"
;;
cmd2)
echo "Executing command $command"
./smallcmd2 "$#"
;;
'')
echo 'No option specified'
exit 1
;;
*) echo "Invalid option"
exit 1
;;
esac
exit $?
Where smallcmds are your secondary command scripts or programs.
Now you can execute it:
./mycommand smallcmd1
Additional parameters can be passed as well.
If you place this script into any $PATH directory then you can omit ./ like so:
mycommand smallcmd1
Making an executable with Thor is really simple. All you have to do is:
include the ruby shebang line.
require "thor" in your script.
define your Thor class.
add #{YourThorClassname}.start to the bottom of your script.
Example: my-cli.rb
#!/usr/bin/env ruby
require "thor"
class MyCLI < Thor
desc "foo", "Prints foo"
def foo
puts "foo"
end
end
MyCLI.start
Make the script executable:
chmod a+x my-cli.rb
Now you can type:
./my-cli.rb foo
You can find a similar example and more help in the Thor Wiki.
You can even rename the file to my-cli (without the .rb extension) and it still works because of the ruby shebang inside the file.

How do I to run a command in Linux as a Ruby script?

Let's say I have some terminal commands like:
sudo mycommand1
mycommand2
#.....
What should I do run them via ruby script (not bash) in Ubuntu?
UPDATE:
I have a ruby script:
def my_method1()
#calculating something.....
end
def method2(var1, var2)
#how do I sudo mycommand1 and any other Lunix command from here?
end
def method3(var4)
#calculating something2....
end
You can do system, exec, or place the command in backticks.
exec("mycommand") will replace the current process so that's really only pratical at the end of your ruby script.
system("mycommand") will create a new process and return true if the command succeeded and nil otherwise.
If you need to use the output of your command in your Ruby script use backticks:
response = 'mycommand`
There are many questions on SO that answer this. However you can run a command in many ways using system, exec, (backticks), %x{} or using open3. I prefer to use open3 -
require 'open3'
log = File.new("#{your_log_dir}/script.log", "w+")
command = "ls -altr ${HOME}"
Open3.popen3(command) do |stdin, stdout, stderr|
log.puts "[OUTPUT]:\n#{stdout.read}\n"
unless (err = stderr.read).empty? then
log.puts "[ERROR]:\n#{err}\n"
end
end
If you want to know more about other options you can refer to Ruby, Difference between exec, system and %x() or Backticks for links to relevant documentation.
You can try these approaches:
%x[command]
Kernel.system"command"
run "command"
make some file.rb with:
#!/path/to/ruby
system %{sudo mycommand1}
system %{mycommand2}
and the chmod the file with exec permissions (e.g. 755)
It you need to pass variables between the two commands, run them together:
system %{sudo mycommand1; \
mycommand2}

Resources