Accessing a ruby property in bash shell - ruby

I am trying to install and execute a ruby gem in my bash shell and I want to look at certain properties of the result in my shell script. How do I do this?
#!/bin/bash -l
source "/usr/local/rvm/scripts/rvm"
rvm use 2.4.0
gem install graphql-schema_comparator
result="$(schema_comparator compare "$NEW_SCHEMA" "$CURRENT_LIVE_SCHEMA")"
Here is the ruby gem: https://github.com/xuorig/graphql-schema_comparator
I want to be able now access the result of the comparison and perform some actions based on it?
a="$(result?.foo)"
b="$(result.bar)"
Both these are failing with the error
result?.foo: command not found
result.bar: command not found

This won't work because
result="$(schema_comparator compare "$NEW_SCHEMA" "$CURRENT_LIVE_SCHEMA")"
If you are running this as a shell script result will only be a string in your shell with whatever your method call outputs to STDOUT. It is not a ruby object and so no ruby commands can be called on it. All you can do with the shell variable is whatever shell will support if you access it in shell with $result.
Why do you even want to do this? Why not just use ruby directly?

Related

In Ruby, on osx, how can I change the prompt from within a ruby script?

In Ruby, on osx, how can I change the prompt from within a ruby script?
For example,
I'd like a ruby script to run some code and depending on the result, do PS1='\w$ '. or PS1='\t$ '
i.e.
~ $PS1='\w $'
~ $
~ $PS1='\t $'
20:52:23 $
So as a start I've just tried a script to change the prompt
~/$ cat scripttochangeprompt.rb
`export PS1='\t$ '`
~/$
but it doesn't change the prompt.
~/$ ruby ./scripttochangeprompt.rb
~/$
I can guess that it's creating a new console session to run the command then closing that new console session. But how can I get it to run it in this console session?
Ruby will always run in a subprocess. A subprocess cannot change the environment of a parent process. However, it can output things in a format that is convenient for parent process to evaluate. This is how e.g. ssh-agent sets its environment variables.
#!/usr/bin/env ruby
puts "export PS1='\t$ '"
Then execute it like this:
eval `changeprompt.rb`
There are several ways to work with shell command execution and you use the one that executes the command in the current ruby process and returns its result to your script. With such an approach this proccess cannot mutate a shell it was called from, so it is unfitting. Other ways of interaction with the shell also use child processes or current ruby process one way or another. Unfortunately, in most OS you cannot set an environment variable of parent process(namely, shell) from child process(namely, your ruby script). Here are stackoverflow issue and an article on that matter. There are some hacks in the issue provided that can satisfy you in practice, but they seem obscure and awkward to me.

How to run a .txt file which has Ruby script, without using the ruby command in the command line

I'm attempting to run some ruby script in a .txt file from the command line. If I use the ruby command before I run the command, the output is what was desired, e.g.
ruby file_name.txt 10 40
How could I execute the same command without having to use the ruby command?
If you are on a unix, you put a #!/usr/bin/ruby at the top of it and the bash shell will execute it.
If you are on Windows, I believe you must use the correct suffix, .rb or .rbw.

Why can't I call `history` from within Ruby?

I can run Bash shell commands from with a Ruby program or irb using backticks (and %x(), system, etc). But that does not work with history for some reason.
For example:
jones$ irb --simple-prompt
>> `whoami`
=> "jones\n"
>> `history`
(irb):2: command not found: history
=> ""
From within a Ruby program it produces this error:
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31: command not found: history
In bash itself, those commands work fine
It's not that the Ruby call is invoking a new shell - it simply does not find that command...
Anyone know why? I'm stumped...
Most unix commands are implemented as executable files, and the backtick operator gives you the ability to execute these commands from within your script. However, some commands that are interpreted by bash are not executable files; they are features built-in to the bash command itself. history is one such command. The only way to execute this command is to first execute bash, then ask it to run that command.
You can use the command type to tell you the type of a particular command in order to know if you can exec it from a ruby (or python, perl, Tcl, etc script). For example:
$ type history
history is a shell builtin
$ type cat
cat is /bin/cat
You'll also find that you can't exec aliases defined in your .bashrc file either, since those aren't executable files either.
It helps to remember that exec'ing a command doesn't mean "run this shell command" but rather "run this executable file". If it's not an executable file, you can't exec it.
It's a built-in. In general, you can run built-ins by manually calling the shell:
`bash -c 'history'`
However, in this case, that will probably not be useful.
{~} ∴ which history
history: shell built-in command

using ruby popen wrapped in a shell script

I finished my short file for a homework assignment which uses IO.popen("command").readlines to grab the STDOUT of that command. However, I need to write a shell script to wrap my ruby file in. No problem, but somehow putting it in the shell script makes readlines hang.
ruby script.rb foo example > example.out
this works
script.sh foo example >example.out
this hangs on readlines. ruby script.rb is all that script.sh contains.
Looks like you forgot to pass your arguments to the ruby command. You may also be failing to specify an interpreter
script.sh
#!/bin/sh
ruby script.rb "$#"
Alternatively you could just add #!/usr/bin/ruby to the top of script.rb and make it executable (chmod +x script.rb). It's not a shell script. But it's generally the preferred way of executing a script in an interpretive language.
Once that's done you can run it with
./script.rb

How to automatically export oracle environment variable required to run a ruby script?

My ruby script requires connection to an Oracle database. So I need to export ORACLE_HOME and LD_LIBRARY_PATH correctly before the script would run. Is there a way that I can export those env variables without using shell script? I tried to put ENV['ORACLE_HOME'] = '/usr/local/oracle_client' at the first line of the script and it doesn't work.
Now the only way it would work is to write a shell script, where export those variables and then run ruby there. The shell script looks like:
export ORACLE_HOME='/usr/local/oracle_client'
export LD_LIBRARY_PATH='/usr/local/oracle_client/lib'
ruby myscript.rb --options
It's kinda ugly because user has to go inside the shell script to change options. I'm wondering whether there's a better way of doing it. So user can just do at command line: ruby myscript.rb --options
Why not supply the ruby options as arguments to the shell script? E.g.,
#!/bin/bash
export ORACLE_HOME='/usr/local/oracle_client'
export LD_LIBRARY_PATH='/usr/local/oracle_client/lib'
ruby myscript.rb $*
Obviously you may want to add argument reasonableness checks, etc., but this gives the idea.
Why not call it out via Kernel.system?
system("export ORACLE_HOME='/usr/local/oracle_client'")
system("export LD_LIBRARY_PATH='/usr/local/oracle_client/lib'")

Resources