I am confused about Ruby command-line options. Both -C dir and -X dir remove directory, but how do they differ from each other?
How does -x [dir] differ from -X dir?
What does -I dir do (I know that it adds dir as the directory for loading libraries)?
Let's create a test.rb file in home directory with following:
hello
#!/usr/bin/ruby
p "here"
Now if we try to run it:
ruby -C /home/my_home test.rb
Which means change working directory to /home/my_home and run test.rb you will get an error:
test.rb:1:in `<main>': undefined local variable or method `hello' for main:Object (NameError)
If we run it with:
ruby -x /home/my_home test.rb
We will get "here" printed and get no error. The main difference between -x and -C is that -x removes everything before the #!/usr/bin/ruby line. And you don't have to set directory to cd too, when using -x. Because the main purpose of -x is to remove lines and it just includes -C functionality too, if needed.
cd /home/my_home; ruby -x test.rb
See (ruby --help)
-Cdirectory cd to directory, before executing your script
-x[directory] strip off text before #!ruby line and perhaps cd to directory
As for -I. You can provide the directories that ruby will search for the file you execute or require.
ruby -x test.rb
Ruby will not find the test.rb file unless you are in /home/my_home. But if you add -I ruby will look for test.rb in "/home/my_home" too.
ruby -x -I/home/my_home test.rb
The difference with -C is that it will not change directory before executing, but will just search for files there.
As you can see from man ruby or some docs online, -C and -X is the same.
And -I will add some dir to ruby LOAD_PATH. For example, I have ./a/my.rb and `./test.rb' like this:
# ./a/my.rb
def hello
puts 'hello from a/my'
end
# ./test.rb
require 'my'
hello
And I execute ruby -I ./a test.rb. This will print hello from a/my. Without -I, ruby will report an error: cannot load such file -- my, because ./a is not in current LOAD_PATH.
-C and -X options do the same job (Changes directory before executing). There is no difference.
-I option is used for adding path to $LOAD_PATH
For example: Assume you have ruby file called my_print_class.rb in my_lib directory
my_print_class.rb:(~/my_lib/my_print_class.rb)
class MyPrintClass
def self.my_print(str)
puts str
end
end
Now you have my_call.rb in home(~).
~/my_call.rb:
require 'my_print_class'
MyPrintClass.my_print("Hello world")
For this you need path of my_print_class so you use ruby -I my_lib my_call.rb
http://www.tutorialspoint.com/ruby/ruby_command_line_options.htm
Related
When I am in a symbolic liked directory (ln -s ...) and invoke Ruby's Dir.pwd it returns the path of the target directory. I need a way to return the link directory like Linux's pwd do. The following script exemplify my need:
#!/bin/bash
set -u
set -e
rm -rf '/tmp/root_dir'
mkdir -p '/tmp/root_dir'
mkdir '/tmp/root_dir/target_dir'
ln -s '/tmp/root_dir/target_dir' '/tmp/root_dir/symlink_dir'
echo "== Printing Linux PWD =="
(cd '/tmp/root_dir/symlink_dir'; pwd)
echo "== Printing Ruby version =="
ruby --version
echo "== Printing IRB version =="
irb --version
echo "== Printing Ruby PWD =="
(cd '/tmp/root_dir/symlink_dir'; echo 'puts ::Dir.pwd' | irb --noecho --noverbose)
echo "=== Running command \"pwd\" in Ruby ==="
(cd '/tmp/root_dir/symlink_dir'; echo 'system("pwd")' | irb --noecho --noverbose)
Output:
/tmp/root_dir/symlink_dir
== Printing Ruby version ==
ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-linux]
== Printing IRB version ==
irb 1.2.6 (2020-09-14)
== Printing Ruby PWD ==
/tmp/root_dir/target_dir
=== Running command "pwd" in Ruby ===
/tmp/root_dir/target_dir
How can I get the symbolic link path as the current path instead of target path using Ruby?
Edit 1: added result for system('pwd') executed in Ruby.
Do you think using system('pwd') would be sufficient?
It definitely will give you the result you are after. But it looks like a hackish solution for me!
I went with:
ENV['PWD'] || ::Dir.pwd
I got no other way to get the link directory in Linux than getting the value of environment variable PWD. When is not present (Other plataforms?) it uses the default way to get current directory in Ruby.
Let's say I have a bash script called program stored in /home/user/program. But then I create a sym link to the bash script using ln -s /home/user/program /usr/bin/program. Then I cd /usr/home/anotherdirectory and then run program. How do I get the bash script to print /usr/home/anotherdirectory to tell me where it was called from?
I tried echo $PWD and it only printed out /usr/bin
This should do the job in your script:
dirname $(readlink -e "$0")
From man readlink:
-e:canonicalize by following every symlink in every component of the given name recursively, all components must exist
I am trying to assign the output of mkdir command to a variable. So I can use the directory further.
-bash-4.1$ pwd
/user/ravi/myscripts/tmpdata
-bash-4.1$ OUTPUT=$(mkdir tmpbkp.`date +%F`)
-bash-4.1$ ls | grep tmp
tmpbkp.2017-04-06
-bash-4.1$ echo "$OUTPUT"
But the directory name is not assigning to the variable. Could you please correct me where I am wrong.
When you run the mkdir command by itself, look how much output it produces:
$ mkdir foo
$
None!
When you use a command substitution to generate the argument to mkdir, look how much extra output you get:
$ mkdir tmpbkp.`date +%F`
$
None!
When you put it inside $() it still produces no output.
There is a -v option for mkdir (in the GNU version at least) which produces some output, but it's probably not what you want.
You want the name of the directory in a variable? Put it in a variable first, then call mkdir.
$ thedir=tmpbkp.`date +%F`
$ mkdir $thedir
$ echo $thedir
tmpbkp.2017-04-06
$
I am using a bash script to launch a ruby script.
this works very well if you are in the sir of the script but if you are not in that dir the script acts funny because it is not on the file path.
#!/bin/sh
jruby -Ilib script.rb $#
I added this to the script.
mypath=`realpath $0`
cd `dirname $mypath`/..
It makes the script run from any place I want. the problem is that its arguments do not get their relative path names changed.
I am using trollop for my input parsing.
My question is: How can I change the input of the path in the input so it will be the correct relative path when I push the args to the ruby script.
I would be happy with a ruby fix to this problem.
This uses bash specifically. It assembles an array of the arguments, calling realpath for each.
#!/bin/bash
mypath=$(realpath $0)
args=()
for arg; do
args+=( "$(realpath "$arg")" )
done
cd "$(dirname "$mypath")"/..
jruby -Ilib script.rb "${args[#]}"
I've liberally sprinkled double quotes throughout the script to handle files and paths that contain spaces.
I ended up doing it this way,
I found using environmental variables worked the best
#!/bin/bash
if [ "$EN_VARE"="" ]
then
EN_VARE="."
fi
jruby -I$EN_VARE/lib $EN_VARE/lib/main_file.rb $#
Is it possible to create an executable script that would be interpreted by make?
I tried this:
#!/usr/bin/env make --makefile=/dev/stdin
main:
#echo Hello!
but it does not work - hangs until press Ctrl-c.
#!/usr/bin/make -f
main:
#echo Hello World!
Is normally all you need in a standard make file. The filename is implicitly passed as the last argument. /dev/stdin here is (usually) the tty. You can do the whole env thing if there's a reason to, but often there's no need.
ajw#rapunzel:~/code/videocc/tools > vi Makefile
ajw#rapunzel:~/code/videocc/tools > chmod a+x Makefile
ajw#rapunzel:~/code/videocc/tools > ./Makefile
Hello World!
The following adds a level of indirection but it's the best solution I've come up with for self-executing makefiles not called "makefile":
#!/bin/sh
exec make -f- "$#" << 'eof'
.PHONY: all
all:
#echo 'hello world!'
I'm trying to collect #! env hacks for each language / program here.