Ruby shell script read from XCode plist - ruby

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.

Related

Mix input/output with Ruby IO?

I am hoping to write a small method that can interact with a subprocess (bash in this case) and should be able to both write commands and have those commands print their outback back to my shell when running the Ruby file.
So far, I can do something similar with this code:
require 'io/console'
#shell = IO.popen('/bin/bash', 'w')
def run(command)
puts command
#shell.puts command
puts 'Done'
end
run 'var=3'
run 'echo $var'
run 'sleep 2'
run 'ls docs'
#shell.close
And then when I run this code all of the Ruby code is printed first, and only later does any of the shell code get printed:
var=3
Done
echo $var
Done
sleep 2
Done
ls docs
Done
3
<ls output>
I was trying to read some of the tests for io/console as I'm almost certain there exists a really straightforward way to interact with a subprocess like this and get the output inline with the commands being run:
https://github.com/ruby/io-console/blob/master/test/io/console/test_io_console.rb

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}

Best way to run an entire script via ruby -e

I've been wanting to run some ruby scripts on remote computers (in a bash shell)
I could create a sequence of bash commands of ruby -e "<command>", but some of these scripts are over 100 lines.
ruby -e with a HEREDOC or %{} & eval() doesn't work well with the mixture of single and double quotes.
Is there a better way to attempt this?
Edit:
The protocol being used is Apple Remote Desktop, which executes these commands in the scope of the remote shell.
If I understand you correctly, you want to run local ruby script on remote machine via SSH or similar protocol. If the script is non-interactive (i.e. doesn't require any user input), you could create it locally and deliver through stdin.
In other words, first write the script and save it locally as, say, foo.rb. Then:
ssh remotehost ruby < foo.rb
That with start the SSH session and execute the remote ruby interpreter. With no arguments, the ruby interpreter executes commands from standard input, and thus we feed SSH with the program on stdin.
As I also want to run ruby scripts via ARD (which I don't think can embed a ctrl-D), I first thought you could combine joraff's solution (to his own problem) with Kelvin's:
cat << ENDOFSCRIPT | ruby
#Here be code ...
ENDOFSCRIPT
Which saves creating/deleting a file.
But there's an even better way:
It turns out (duh) that ARD embeds an EOF or just otherwise terminates what it sends in such a way that you can simply do:
ruby
#Paste whole script here
Works at least in ARD 3.6.1. Win!
This worked:
cat << 'EOF' > /tmp/myscript.rb
# ruby script contents go here. any syntax is valid, except for your limit string (EOF)
EOF
ruby /tmp/myscript.rb;
rm /tmp/myscript.rb;
Since this isn't relying on how an interpreter binary handles stdin-style commands, it will work for most other languages as well (python, perl, php).
Why not send the script over first?
scp foo.rb remotehost:
ssh remotehost "ruby foo.rb"
You could even clean up the file after:
ssh remotehost "rm foo.rb"

How do I pass variables from ruby to sh command

I have a rake task that runs, quite a lot of code. At the end, I need to use sftp and ssh to do some stuff. At the moment I'm unable to automate it. Is there a way to pass to stdout?
This seems like a simple question but I can't find the answer anywhere
#some ruby code
#more ruby code
sh "sftp myuser#hots" #this opens the sftp console
sh "put file" #this doesn't get run until sftp is exited
sh "put another_file" #neither does this
#more ruby code
sh "ssh host" # opens the ssh console
sh "some_action_on_host" # this doesn't get run until ssh is exited
I know there will be ways of doing sftp and ssh using ruby but ideally I just want to be able to pipe variables and commands into the console
So you want to run sftp and send a series of commands to it? How about something like:
sftp = IO.popen("sftp myuser#hots", "w+")
sftp << "put file\n"
sftp << "put another file\n"
sftp.flush # make sure to include this
If you don't want to use ruby, then you may want to enclose your shell commands into ` (backtick characters). This string will be passed to Kernel.` method. This method execute the text as an OS shell command and returns the command's output as a string, e.g.:
`ls`
Alternative syntax to ` is %x[]. This way you can write any bash script:
%x[sftp myuser#hots <<COMMAND
put #{file}
quit
COMMAND]
Please note that this syntax support ruby expressions interpolation using #{...} syntax (similar to double-quoted string literals).

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

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")

Resources