Get current path when in a symbolic linked directory - ruby

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.

Related

Uninstalled Anaconda still shows up in PATH (Mac OS X)

I have installed Anaconda a few months ago but then uninstalled it and removed all anaconda files by using
rm -rf ~/anaconda
but when I run
echo $PATH
it still outputs a path that point to an Anaconda folder but when I search for it, it doesn't even exist, why is that happening?
What makes you think that non-existent directory are automatically
removed from $PATH? They are not. As an example I can make a new dir
and go there:
$ mkdir /tmp/new-path-dir && cd /tmp/new-path-dir
Add it to the $PATH:
$ PATH=/tmp/new-path-dir:$PATH
$ echo $PATH
/tmp/new-path-dir:<REST_OF_PATH>
Make a new olleh.so (hello spelled backwards) executable inside
it:
$ echo 'echo hi' > olleh.so && chmod +x olleh.so
Then go back to ~:
$ cd ~
And start a olleh.so:
$ olleh.so
hi
Now I can safely remove /tmp/new-path-dir:
$ rm -r /tmp/new-path-dir/
And it still will be shown in my $PATH:
$ echo $PATH
/tmp/new-path-dir:<REST_OF_PATH>
But I won't be able to run olleh.so any more:
$ olleh.so
bash: /tmp/new-path-dir/olleh.so: No such file or directory
And as paths to executables are cached by bash I can get rid of
olleh.so permanently like this:
$ hash -r
$ olleh.so
bash: olleh.so: command not found

How does RVM gets invoked while going into a folder with Gemfile?

I am surprised at how RVM switches Ruby versions honouring Gemfile just by navigating into the directory via command-line? Is RVM getting a call back through the shell? Can anyone provide a pointer on this?
For instance message like this:
RVM used your Gemfile for selecting Ruby, it is all fine - Heroku does that too,
you can ignore these warnings with 'rvm rvmrc warning ignore /directory/path/to/Gemfile'.
To ignore the warning for all files run 'rvm rvmrc warning ignore allGemfiles'.
According to this post:
https://unix.stackexchange.com/questions/21363/execute-bash-scripts-on-entering-a-directory
rvm redefines the cd command. If I do what Amadan suggested, I get:
~$ type cd
cd is a function
cd ()
{
__zsh_like_cd cd "$#"
}
That looks like some kind of alias, so let's try:
~$ type __zsh_like_cd
__zsh_like_cd is a function
__zsh_like_cd ()
{
typeset __zsh_like_cd_hook;
if builtin "$#"; then
shift || true;
for __zsh_like_cd_hook in chpwd "${chpwd_functions[#]}";
do
if typeset -f "$__zsh_like_cd_hook" > /dev/null 2>&1; then
"$__zsh_like_cd_hook" "$#" || break;
fi;
done;
true;
else
return $?;
fi
}
In a zsh shell, chpwd is a hook function that is called when the current directory changes. But, I'm not sure why that works in a bash shell, which doesn't provide the chpwd hook function. Amadan?
Normally cd is a shell builtin. rvm defines cd function which gets invoked instead. Do this to see for yourself:
$ type cd
Then try it in a "clean" shell, to see the difference:
$ env -i PATH=$PATH HOME=$HOME bash -c "type cd"

rvm install via capistrano is flooding output

I'm running a shell script via capistrano to install rvm and ruby. When running
rvm install ruby-${RUBY_VERSION} 2>&1 > ../log/ruby_install.log
in my script, all output seems to be going to the log file, except for the scrollbar output. that output is being sent back to capistrano and it's flooding the output, and looks horrible.
Is there any way I can hide the progress during the command?
I tried running
alias curl="curl --silent"
before the command, but it doesn't work at all, so I guess the install is happening via some other means.
Try:
gem install rvm-capistrano -v ">=1.3.0.rc11"
It contains code to make curl silent
The answer from #mpapis lead me to the following solution:
# Rename .curlrc if present
if [[ -f $HOME/.curlrc ]]; then
echo "Backing up .curlrc"
mv $HOME/.curlrc $HOME/.curlrc~
fi
# Create a temporary .curlrc configuration file, this prevents curl from flooding the Capistrano output
{
echo "insecure"
echo "silent" # Hide verbose output, it floods the capistrano output
echo "show-error"
} > $HOME/.curlrc
I added the above snippet to my bash script, and at the end, I just restored .curlrc to it's previous state:
rm $HOME/.curlrc
if [[ -f $HOME/.curlrc~ ]]; then
mv $HOME/.curlrc~ $HOME/.curlrc
fi
This is modified from rvm-capistrano, check it out on the original Github Repository.

Command line options

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

TextMate doesn't work with .rvmrc anymore after collegue changed it

Some while ago, our .rvmrc file looked like this (pretty default):
#!/usr/bin/env bash
# This is an RVM Project .rvmrc file, used to automatically load the ruby
# development environment upon cd'ing into the directory
# First we specify our desired <ruby>[#<gemset>], the #gemset name is optional,
# Only full ruby name is supported here, for short names use:
# echo "rvm use 1.9.3" > .rvmrc
#environment_id="ruby-1.9.3-p0#iq"
environment_id="ruby-1.9.3-p0"
# Uncomment the following lines if you want to verify rvm version per project
# rvmrc_rvm_version="1.14.1 (master)" # 1.10.1 seams as a safe start
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
# return 1
# }
# First we attempt to load the desired environment directly from the environment
# file. This is very fast and efficient compared to running through the entire
# CLI and selector. If you want feedback on which environment was used then
# insert the word 'use' after --create as this triggers verbose mode.
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
then
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
else
# If the environment file has not yet been created, use the RVM CLI to select.
rvm --create "$environment_id" || {
echo "Failed to create RVM environment '${environment_id}'."
return 1
}
fi
# If you use bundler, this might be useful to you:
# if [[ -s Gemfile ]] && {
# ! builtin command -v bundle >/dev/null ||
# builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
# }
# then
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
# gem install bundler
# fi
# if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
# then
# bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
# fi
To be used with RubyMine, a collegue changed it to the following
rvm ruby-1.9.3-p0 --create
The bad is, that my TextMate now automatically switches to Ruby 1.8.7 when executing a file from within the folder, so it doesn't work with this anymore (but before, it did by setting the TM_RUBY variable to /Users/josh/.rvm/bin/rvm-auto-ruby). As I'm the only TextMate user, I'm on my own now to figure out what's wrong. Anybody has an idea?
When I remove the .rvmrc file, then it loads the default RVM ruby version - if it's there, it loads the system ruby (1.8.7).
I also tried the wrapper approach, described on the rvm page, but this also loads the system ruby (1.8.7).
Thanks for any help! Josh
check the docs at RVM Site Texmate integration

Resources