pyenv installation script: need help understanding what it does - bash

One of the steps to install pyenv requires typing the following into a terminal:
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
While I understand what echo -e and >> ./bash_profile do, I do not really understand what is going on inside the quotations marks.
After running the command above, my bash_profile now has the following:
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
Question: Could you explain what this code does? Is my interpretation of what is happening (see below) correct?
Interpretation:
command -v takes the name of a command and outputs its description, if the command given does not exist nothing is outputted; thus command -v pyenv will output the description pyenv if it is available (which will be if you installed pyenv), otherwise it will not show anything
the 1>/dev/null takes the output of the command -v pyenv and throws it away
What is the purpose for 2>&1?
Why do we need the eval inside the if block? Can't we just run pyenv init - directly?
Thanks for helping!

Related

Homebrew is not found on apple silicon

I have just installed brew on my new laptop but when I try and run brew its tells me there is no such command. What could I be doing wrong?
tomsmail#MacBook-Air ~ % brew
zsh: command not found: brew
I have fully installed brew along with the necessary xcode terminal commands.
Run:
echo $SHELL
If your shell shown is zsh, do this:
echo "eval $(/opt/homebrew/bin/brew shellenv)" >> ~/.zprofile
If yor shell is bash, run this:
echo "eval $(/opt/homebrew/bin/brew shellenv)" >> ~/.bash_profile
If the result is csh, run this command:
/opt/homebrew/bin/brew shellenv >> ~/.cshrc
Running the bellow command should solve the issue
eval $(/opt/homebrew/bin/brew shellenv)
Answer found here: https://apple.stackexchange.com/a/413207

how to echo $(command) into bash profile

I am trying to append eval "$(rbenv init -)" to my bash profile
(I am trying to follow this instruction)
# Load rbenv automatically by appending
# the following to ~/.bash_profile:
eval "$(rbenv init -)"
This is part of an automated process so I don't have access to a GUI or can't use an editor. but when I echo the command $(rbenv init -) gets executed and append bunch of stuff. How can I echo it as plain text?
this is what I have now
ec2-user#ip-172-31-46-129 ~ % cat /tmp/install-rbenv.sh
+-zsh:41> cat /tmp/install-rbenv.sh
#!/bin/bash
sudo -i -u buildkite-agent bash << EOF
echo "export RUBY_CONFIGURE_OPTS=\"--with-openssl-dir=$(brew --prefix openssl#1.1)\"" >> /Users/buildkite-agent/.bash_profile
echo 'eval "$(rbenv init -)"' >> /Users/buildkite-agent/.bash_profile
EOF
echo "Done"
running it
ec2-user#ip-172-31-46-129 ~ % . /tmp/install-rbenv.sh
+-zsh:42> . /tmp/install-rbenv.sh
+/tmp/install-rbenv.sh:6> brew --prefix openssl#1.1
+/tmp/install-rbenv.sh:6> rbenv init -
+/tmp/install-rbenv.sh:6> sudo -i -u buildkite-agent bash
+/tmp/install-rbenv.sh:10> echo Done
Done
checking the bash profile
ec2-user#ip-172-31-46-129 ~ % sudo su - buildkite-agent
+-zsh:43> sudo su - buildkite-agent
rbenv: no such command `sh-'
-bash: eval: line 31: syntax error near unexpected token `rehash'
-bash: eval: line 31: ` rehash|shell)'
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
ip-172-31-46-129:~ buildkite-agent$ cat ~/.bash_profile
export RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local/opt/openssl#1.1"
eval "export PATH="/Users/ec2-user/.rbenv/shims:${PATH}"
export RBENV_SHELL=zsh
source /usr/local/Cellar/rbenv/1.1.2/libexec/../completions/rbenv.zsh
command rbenv rehash 2>/dev/null
rbenv() {
local command
command="${1:-}"
if [ "$#" -gt 0 ]; then
shift
fi
case "$command" in
rehash|shell)
eval "$(rbenv "sh-$command" "$#")";;
*)
command rbenv "$command" "$#";;
esac
}"
Apparently you don't want to use an editor to edit your .bash_profile file or you are afraid you will got trapped inside vi :-D
Put the text you want to append to the file in apostrophes and it will go verbatim to the file. The shell does not do any expansion in the arguments that are wrapped in apostrophes.
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
That's all.
Use apostrophes around the first EOF, i.e. 'EOF' instead of EOF. bash distinguishes between the two and won't evaluate stuff if you use the apostrophe version.
> bash << EOF > test.sh
echo '$(date)'
EOF
> cat test.sh
Mon 12 Apr 2021 08:08:53 PM CEST
> bash << 'EOF' > test.sh
echo '$(date)'
EOF
> cat test.sh
$(date)

why is executing a command in the sh terminal failing

I am using ubuntu.
When I do this from the terminal
echo $SHELL
I got /bin/bash
and then when I do
echo "`$SHELL -c 'echo $BASH_VERSION'`"
I got 4.4.20(1)-release
Then, I try to do the same thing inside a particular docker container I am running, but as you will see this has the sh terminal not the bash terminal
so from that container
echo $SHELL
I got /bin/sh
that I have read is a link to dash
then with
echo $BASH_VERSION
I got
4.3.48(1)-release
so I do
echo "`$SHELL -c 'echo $BASH_VERSION'`"
and I got nothing.
Can someone explain me what is happening?
How can you run a sh terminal in ubuntu
Any aditional resource to understand shells is welcome too
I specially don't understand why when doing the echo $BASH_VERSION I got something but then with the latter I got nothing if the shell is the same

Making bash script continue after exec $SHELL

I'm making a bash script that would install rbenv and ruby.
cd
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL
rbenv install $rubyVersion
rbenv global $rubyVersion
But when the exec $SHELL is called the bash process is replaced by new bash process and the script stops (of course).
How can I make the script to continue?
It appears that you're trying to achieve multiple objectives by modifying the .bashrc file then calling exec $SHELL. Neither of those actions will modify the shell-in-which-this-script-is-running. To modify the current shell, you want to "source" the .bashrc file. Use the "dot notation" instead of calling exec $SHELL:
. ~/.bashrc
Good luck with this one!
replace exec $SHELL lines with "$SHELL" lines or completely remove those lines

Unreachable command in a shell script code while installing Oh My Zsh

Here is my sample1.sh:
#!/bin/bash
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
echo "foo"
Output:
Here is my sample2.sh:
#!/bin/bash
rm -rf ~/.oh-my-zsh
rm ~/.zshrc
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
echo "foo"
Output:
As you see, the only difference between above snippets are below lines:
rm -rf ~/.oh-my-zsh
rm ~/.zshrc
Question: why am I able to see foo, only when OMZ is already installed? What's so specific inside https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh, that after it detects that OMZ does not exist and can be installed, after successful installation, it doesn't continue to reach my foo?
Obviously, that echo "foo" was just an example to highlight the general problem.
In the final built of the script, what I want to achieve is to simply enable some plugins once OMZ is installed by calling:
sed -i '' -e 's/^plugins=.*/plugins=(git, sublime)/' ~/.zshrc
This line works fine only when I trigger it manually. The problem is that it never calls sed once OMZ is installed. Thanks for pointing out, where is the problem that I don't understand.
Part of the install script for OMZ is to switch the current shell to sh with the line env zsh. I believe that this is basically causing your script to fork ZSH and never actually finish running. If you exit from the ZSH shell then it should continue as normal.
Oh-my-zsh will fork the current process. To fix, just cut it out of the script.
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sed "s/env zsh//g")"
As a workaround, you can use & and wait to run the install command in parallel and wait for its completion.
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" &
wait
echo "foo"
Thanks #mgild for the idea, that was exactly what I was looking for. Just one thing - the command should be:
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sed "s/env zsh.*//g")"
So that sed removes the whole and not just "env zsh" substring.

Resources