Why does "rvm use" command require/suggest a login shell? - rvm

With a default installation of RVM and from a non-login shell, executing rvm use produces:
RVM is not a function, selecting rubies with 'rvm use ...' will not work.
You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for an example.
Where the reason for this warning is that the following sourcing line is added only in files like ~/.bash_profile during installation:
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
And the previous can even be confirmed as expected behavior from https://rvm.io/support/faq#shell_login:
RVM by default adds itself currently to ~/.bash_profile file, and the
recommended way is to enable login shell in gnome-terminal (and
screen).
But, why isn't the RVM installer simply adding the previous line in files like ~/.bashrc so commands like rvm use work both for login and non-login shells?.
Similar questions without a proper/official answer:
Why rvm needs login shell?
https://askubuntu.com/questions/444880/why-do-i-need-to-run-bin-bash-login

The main reason here is that rvm must be defined as a function of your shell and not as a rvm-use script.
If defined as a script, rvm-use would operate in a separate subprocess and only had an access to a copy of your shell environment, not to the original env. Because rvm use needs to actually modify your local PATH environment (to prepend rvm ruby shims for correct version) it needs full access to your shell environment - hence use of function is required.
This means, you need to load this function somewhere - it is (most likely, didn't fully check it) done via /etc/profile, which loads /etc/profile.d/rvm.sh file. This file needs to be either manually sourced or is loaded automatically when terminal opens as a login shell.
Now, why does rvm needs to modify local terminal environment instead of using single global state? It is to allow us to have few terminals open with different ruby versions active at the same time.

Related

Github Actions, permission denied when using custom shell

I am trying to use a shell script as a custom shell in Github Actions like this:
- name: Test bash-wrapper
shell: bash-wrapper {0}
run: |
echo Hello world
However, when I try to run it, I get Permission denied.
Background: I have set up a chroot jail, which I use with QEMU user mode emulation in order to build for non-IA64 architectures with toolchains that lack cross-compilation support.
The script is intended to provide a bash shell on the target architecture and looks like this:
#!/bin/bash
sudo chroot --userspec=`whoami`:`whoami` $CROSS_ROOT qemu-arm-static /bin/bash -c "$*"
It resides in /bin/bash-wrapper and it thus on $PATH.
Digging a bit deeper, I found:
Running bash-wrapper "echo Hello world" in a GHA step with the default shell works as expected.
Running bash-wrapper 'echo Running as $(whoami)' from the default shell correctly reports we are running as user runner.
Removing --userspec from the chroot command in bash-wrapper (thus running the command as root) does not make a difference – the custom shell gives the same error.
GHA converts each step into a script file and passes it to the shell.
File ownership on these files is runner:docker, runner being the user that runs the job by default.
Interestingly, the script files generated by GHA are not executable. I suspect that is what is ultimately causing the permission error.
Indeed, if I modify bash-wrapper to set the executable bit on the script before running it, everything works as expected.
I imagine non-executable script files would cause all sorts of troubles with various shells, thus I would expect GHA would have a way of dealing with that – in fact I am a bit surprised these on-the-fly scripts are not executable by default.
Is there a less hacky way of fixing this, such as telling GHA to set the executable bit on temporary scripts? (How does Github expect this to be solved?)
When calling your script try running it like this:
- name: Test bash-wrapper
shell: bash-wrapper {0}
run: |
bash <your_script>.sh
Alternatively, try running this command locally and the commit and push the repository:
git update-index --chmod=+x <your_script>.sh

Flatpak Intellij Idea - problem with subversion executable

After installing Intellij Idea using flatpak on Clear Linux I'm not able to make it run svn executable.
I added ---filesystem=host to flatpak permissions and tried to set executable path to /run/host/usr/bin/svn but with no luck (path is available/exists, though Intellij keeps complain)
svn command is normally available from system terminal.
When I try to run /run/host/usr/bin/svn command via Intellij Idea built-in terminal, I've got error that library is not available:
sh-5.0$ /run/host/usr/bin/svn
/run/host/usr/bin/svn: error while loading shared libraries: libsvn_client-1.so.0: cannot open shared object file: No such file or directory
I also tried set flatpak-spawn. Following command works perfectly fine in Intellij Idea built-in terminal:
/usr/bin/flatpak-spawn --host /usr/bin/svn, though when set as path to svn executable still gives me Intellij Idea error:
"The path to Subversion executable is probably wrong"
Could anybody please help with making it work?
TLDR: You probably need to add the path to svn into your IntelliJ terminal Path.
Details:
It looks like you are having a path issue. I had a similar problem running kubectl running PyCharm installed from a flatpak on Pop_Os.
If I try to run kubectl I see the following:
I have kubectl installed in /usr/local/bin. This is a screenshot from my 'normal' terminal.
In the PyCharm terminal this location is mounting under /run/host/usr/local/bin/.
If I look at my path in the PyCharm terminal, it is not there.
So I'll add the /run/host/usr/local/bin/ to my path and I can then run kubectl:
To make sure this comes up all the time, I need to add the PATH to the Terminal settings:
I can now execute any of the commands in my /usr/local/bin dir.
I found a really ugly solution for dealing with SVN with the JetBrains family, which does actually answer the question. But in a very roundabout way. Unfortunately Alex Nelson's solution didn't work for me.
You would think the Flatpak would come with a valid SVN, since it's actually part of the expected requirements for the program...
When in the terminal, you can run
cd ..
/usr/bin/flatpak-spawn --host vim ./svn
Then press i to go into input mode, then paste the following in the opened text file (Basically what it does is create an executable which passes it to the flatpak-spawn invocation):
#!/bin/bash
/usr/bin/flatpak-spawn --host /usr/bin/svn $#
Save and quit from vim (ESC, then :wq!). Make it executable:
chmod +x svn
Then in IntelliJ's menu, set the "path to svn" to
/home/<yourusername>/IdeaProjects/svn
It's worked for everything I've tried... Hope this helps out anyone else who was struggling with this.
I am using a similar solution to caluga.
#!/bin/sh
cd
exec /usr/bin/env -- flatpak-spawn --host /usr/bin/env -- svn "$#"
exec makes it replace the wrapper script process so the wrapper script process can end.
I'm using /bin/sh instead of /bin/bash as bash features are not needed.
using /usr/bin/env, but maybe not necessary if PATH is set up right.
remember to quote "$#" in case there are spaces in arguments.
I am putting it in ~/.local/bin and referencing it with its absolute path in the IntelliJ settings (Settings -> Version Control -> Subversion -> Path to Subversion executable).
I also was running into problems with IntelliJ saying that /app/idea-IC path does not exist. Figured that something outside the flatpak (i.e. svn or env) was trying to change directory to the working directory from where the wrapper script was invoked (inside the flatpak). Using cd allows the wrapper script to change to a directory that exists both inside the flatpak and on the host.
Fedora Silverblue or toolbox users might want to use dev tools inside their toolbox, in which case you can do:
#!/bin/sh
cd
exec /usr/bin/env -- flatpak-spawn --host toolbox run svn "$#"

Adding home-brew to PATH

I just installed Home-brew and now I'm trying to insert the home-brew directory at the top of my path environment variable by typing in two commands inside my terminal. My questions are these:
What is a path environment variable?
Are the two codes provided me correct?
echo "export Path=/usr/local/bin:$PATH" >> ~/.bash_profile && source ~/.bash_profile
After this I am to type in brew doctor. Nothing is happening as far as I can see.
Can anyone offer me some advice or direction?
I installed brew in my new Mac M1 and ask me to put /opt/homebrew/bin in the path, so the right command for this case is:
echo "export PATH=/opt/homebrew/bin:$PATH" >> ~/.bash_profile && source ~/.bash_profile
TL;DR
echo "export PATH=/usr/local/bin:$PATH" >> ~/.bash_profile && source ~/.bash_profile
is what you want.
To answer your first question; in order to run (execute) a program (executable) the shell must know exactly where it is in your filesystem in order to run it. The PATH environment variable is a list of directories that the shell uses to search for executables. When you use a command that is not built into the shell you are using the shell will search through these directories in order and will execute the first matching executable it finds.
For example when you type: mv foo bar the shell is almost certainly actually using an executable located in the /bin directory. Thus fully the command is
/bin/mv foo bar
The PATH environment variable therefore saves you some extra typing. You can see what is in your PATH currently (as you can with all environment variables) by entering:
echo $<NAME OF VARIABLE>
So in this instance:
echo $PATH
As I mentioned earlier, ordering is important. Adding /usr/local/bin to the beginning of PATH means that the shell will search there first and so if you have an executable foo in that folder it will be used in preference to any other foo executables you may have in the folders in your path. This means that any executables you install with brew will be used in preference to the system defaults.
On to your second question. What the command you have provided is trying to do is add a line to your .bash_profile and then source it. The .bash_profile is a text file stored in your home directory that is sourced (read) every time bash (your shell) starts. The mistake in the line you've provided is that only the first letter of PATH is capitalised. To your shell Path and PATH are very different things.
To fix it you want:
echo "export PATH=/usr/local/bin:$PATH" >> ~/.bash_profile && source ~/.bash_profile
To explain
echo "export PATH=/usr/local/bin:$PATH"
simply prints or echoes what follows to stdout, which in the above instance is the terminal. (stdout, stderr and stdin are very important concepts on UNIX systems but rather off topic) Running this command produces the result:
export PATH=/usr/local/bin:/opt/local/sbin:/opt/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
on my system because using $PATH within double quotes means bash will substitute it with its value. >> is then used to redirect stdout to the end of the ~/.bash_profile file. ~ is shorthand for your home directory. (NB be very careful as > will redirect to the file and overwrite it rather than appending.)
&& means run the next command is the previous is successful and
source ~/.bash_profile
simply carries out the actions contained in that file.
As per the latest documentation, you need to do this:
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/dhruv/.bashrc
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
Now you should be able to run brew from anywhere.
When you type in a program somewhere and click enter, it checks certain locations to see if that program exists there.
Linux brew uses locations different from the normal linux programs, so we are adding these locations to the ~/.profile file which sets the paths.
Run this in your terminal, and it will place the correct code in the .profile file, automatically.
echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
Don't use .bash_profile because when you use something different from bash, like zsh, it may not work. .profile is the correct location.

Set up PATH correctly for zsh and RVM

I just switched to ZSH and are having issues with RVM. I believe it is related to my PATH. One issue that I have is when I start a new tab in iTerm2, the ruby version switches to 1.9.3 even though the default is 2.0.0. Here is my .zshrc file.
export PATH="/Users/okyretina/.rvm/gems/ruby-2.0.0-p353#iou-web/bin:$PATH:$HOME/.rvm/bin:/Users/okyretina/.rvm/gems/ruby-1.9.3-p429#rails-3.2.13/bin:/Users/okyretina/.rvm/gems/ruby-1.9.3-p429#global/bin:/Users/okyretina/.rvm/rubies/ruby-1.9.3-p429/bin:/Users/okyretina/.rvm/bin:/Users/okyretina/bin:/Users/okyretina/xbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/okyretina/phantomjs/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/share/npm/bin"
# load RVM
# insure /usr/local/bin comes before /usr/bin
# PATH="/usr/local/bin:/usr/local/sbin:$PATH"
PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
# This command should be at the end for it loads the oh-my-zsh.sh script
source $ZSH/oh-my-zsh.sh
my export PATH is very long but I'm not sure which one is no longer needed.
run:
rvm get stable --auto-dotfiles
it will reorganize your shell initialization files to load rvm in proper places, make sure to read all the output - it does print information and warnings that are important.
Probably my answer won't help you to solve your particular problem but I will try to help you in finding a solution.
Your $PATH is pretty long and it's hard to make sure that the files have a correct order. In zsh you can set $PATH like this (example taken from my config):
typeset -U path
path=(
/usr/local/{bin,sbin}
/usr/local/git/bin
/usr/local/opt/coreutils/libexec/gnubin
$path
)
As you can see this method much better in terms of readability and it can help you to make sure that the order in $PATH is correct.
Also in your paths you use both "/Users/okyretina/" and $HOME. I think it makes sense to use $HOME in all cases so your paths will look much shorter and it will be easier to read them.

how to set up the psql command in cygwin?

I have a local dev site on my machine with Apache server and PostgreSQL 9.1 database. As I'm using Windows, I also installed Cygwin. I want to access to database and make some queries via Cygwin insead of pgAdmin III, but it tells me that psql command not found. How should I set up the psql command in cygwin?
As of today, you just have to install postgresql-client package in cygwin:
Run your cygwin setup.exe file (this can be run multiple times to
add more packages).
Type postgresql into the search box, select postgresql-client and
press "next" to install.
Now you can open Cygwin terminal and type psql to run!
The best combo for Cygwin on Windows, I've found, is the normal Windows Postgres installation combined with Cygwin psql.
Cygwin psql (and other command-line tools) can be compiled from source fairly easily. Here's the steps for 9.2.4:
$ wget http://ftp.postgresql.org/pub/source/v9.2.4/postgresql-9.2.4.tar.bz2
$ tar xjf postgresql-9.2.4.tar.bz2
$ cd postgresql-9.2.4/
$ ./configure
$ cd src/bin/psql
$ make
This creates a psql.exe binary that works well with Cygwin. However, by default, it tries to connect to the local instance using a Unix socket instead of TCP. So use -h to specify the hostname and force TCP, for example:
$ ./psql -h localhost -U postgres
Move this psql.exe to someplace on your path (e.g. ~/bin) and possibly wrap in a script to add '-h localhost' for convenience when no other arguments supplied.
The source could be modified to change the default, but that takes actual work ;)
If I understand your question correctly you are running cygwin because you want to run queries against PostgreSQL via bash and psql on Windows, right?
Cygwin can run Windows binaries from bash, so install the native Windows builds and make sure psql.exe is in the PATH You should be able to copy the executable if necessary.
There is no need to install a native Cygwin build of PostgreSQL. Just use the existing psql tool, and make sure you can access the Windows-native psql.exe.