Automatically chdir to vagrant directory upon "vagrant ssh"
Asked Answered
D

9

51

So, I've got a bunch of vagrant VMs running some flavor of Linux (centos, ubuntu, whatever). I would like to automatically ensure that a "vagrant ssh" will also "cd /vagrant" so that no-one has to remember to do that whenever they log in.

I've figured out (duh!) that echo "\n\ncd /vagrant" >> /home/vagrant/.bashrc will do the trick. What I don't know is how to ensure that this only happens if the cd command isn't already there. I'm not a shell expert, so I'm completely confused here. :)

Dupleix answered 25/7, 2013 at 16:49 Comment(0)
G
27

cd is a Bash shell built-in, as long as a shell is installed it should be there.

Also, be aware that ~/.bash_profile is for interactive login shell, if you add cd /vagrant in ~vagrant/.bashrc, it may NOT work.

Because distros like Ubuntu does NOT have this file -> ~/.bash_profile by default and instead use ~/.bashrc and ~/.profile

If someone creates a ~/.bash_profile for vagrant user on Ubuntu, ~vagrant/.bashrc will not be read.

Galactic answered 29/7, 2013 at 21:18 Comment(4)
Where do you configure this inside your vagrant configuration? I assume not creating it inside the VM.Yasui
This answer was helpful, but I found the wording somewhat ambiguous in the case of a Ubuntu VM. This is what worked for me: 1. $ vagrant ssh 2. $ vi .bash_profile in the directory you find yourself in after ssh - if in doubt first go to the home directory using $ cd ~ 3. add cd /vagrant to the file and save.Peta
@Avalos has the correct answer: it uses a Vagrant feature made for this, instead of a homebrewed workaround. BUT, by the way, if you ever want to add end of file if a string "does not" exist, the answer would be: grep foo ~/.bash_profile || echo "foo" > ~/.bash_profile where the || means OR, so part 2 only gets executed if part 1 fails.Galop
To disambiguate .profile, .bashrc and .bash_profile even more: serverfault.com/q/261802/536173Alcaraz
A
37

You can do this by using the config.ssh.extra_args setting in your Vagrantfile:

  config.ssh.extra_args = ["-t", "cd /vagrant; bash --login"]

Then anytime you run vagrant ssh you will be in the /vagrant directory.

Avalos answered 1/8, 2019 at 16:40 Comment(4)
This is a nicer solution than trying to parse/provision the .bashrc file.Bickart
This should be the correct answer. it is the least invasive on other processes in the environment, and speicficly handles the vagrant ssh command.Seaddon
BEST answer for 2020+ (might not have existed in 2013 when question was accepted).Galop
My preferred answer, but note a downside (as of 2.2.14): vagrant ssh -c <cmd> or vagrant ssh -- <cmd> will append to these configured arguments rather than replace them. So, from the host machine, without this config: vagrant ssh -c pwd works fine, but with this config it gives an error: "/bin/bash: cannot execute binary file"Algid
L
29

I put

echo "cd /vagrant_projects/my-project" >> /home/vagrant/.bashrc

in my provision.sh, and it works like a charm.

Lysippus answered 19/9, 2014 at 14:21 Comment(3)
True, it would be even better if someone knew a one liner that would only append it if it isn't there in the file.Lysippus
If you add it to your provision file, add it in the section where it will only run once. If your vm is already set up (and it's not added), run it from the command line. If you're not sure if it's added, open the file in a text editor and check the last line.Euphrasy
This answer is still correct, but now being 2020 I suggest looking at the Vagrant-Ansible provisioner simply because it gives you a somewhat platform-neutral provisioning technology. (But as always, if something isn't broken don't fix it)Galop
G
27

cd is a Bash shell built-in, as long as a shell is installed it should be there.

Also, be aware that ~/.bash_profile is for interactive login shell, if you add cd /vagrant in ~vagrant/.bashrc, it may NOT work.

Because distros like Ubuntu does NOT have this file -> ~/.bash_profile by default and instead use ~/.bashrc and ~/.profile

If someone creates a ~/.bash_profile for vagrant user on Ubuntu, ~vagrant/.bashrc will not be read.

Galactic answered 29/7, 2013 at 21:18 Comment(4)
Where do you configure this inside your vagrant configuration? I assume not creating it inside the VM.Yasui
This answer was helpful, but I found the wording somewhat ambiguous in the case of a Ubuntu VM. This is what worked for me: 1. $ vagrant ssh 2. $ vi .bash_profile in the directory you find yourself in after ssh - if in doubt first go to the home directory using $ cd ~ 3. add cd /vagrant to the file and save.Peta
@Avalos has the correct answer: it uses a Vagrant feature made for this, instead of a homebrewed workaround. BUT, by the way, if you ever want to add end of file if a string "does not" exist, the answer would be: grep foo ~/.bash_profile || echo "foo" > ~/.bash_profile where the || means OR, so part 2 only gets executed if part 1 fails.Galop
To disambiguate .profile, .bashrc and .bash_profile even more: serverfault.com/q/261802/536173Alcaraz
V
8

You need to add cd /vagrant to your .bashrc in the vm. The best way to do this is in your provisioner script.

If you don't have a provisioner script, make one by adding this line to your Vagrantfile before end:

config.vm.provision "shell", path: "scripts/vagrant/provisioner.sh", privileged: false

Path is relative to the project root where the Vagrantfile is, and privileged depends on your project and what else is in your provisioner script which might need to be privileged. I use priveleged false and sudo explicitly when necessary.

And in the provisioner script:

if ! grep -q "cd /vagrant" ~/.bashrc ; then 
    echo "cd /vagrant" >> ~/.bashrc 
fi 

This will add cd /vagrant to .bashrc, but only if it isn't there already. This is useful if you reprovision, as it will prevent your .bashrc from getting cluttered.

Some answers mention a conflict with .bash_profile. If the above code doesn't work, you can try the same line with .bash_profile or .profile instead of .bashrc. However, I've been using vagrant with ubuntu guests. My Laravel/homestead box based on Ubuntu has a .bash_profile and a .profile but having cd /vagrant in .bashrc did work for me when using vagrant ssh without changing or deleting the other files.

Veneration answered 11/2, 2018 at 1:9 Comment(1)
To disambiguate .profile, .bashrc and .bash_profile even more: serverfault.com/q/261802/536173. Therefore, I would recommend to use .bashrc, too.Alcaraz
B
5

You can add cd /vagrant to your .bashrc and it will run the command when you ssh. The /bashrc you want is in /home/vagrant (the user you login as when you vagrant ssh.) You can just stick the new line at the bottom of the file.

Blastocoel answered 26/7, 2013 at 16:43 Comment(0)
I
5

You can also do it this way:

vagrant ssh -c "cd /vagrant && bash"

And you could include it in a script to launch it (like ./vagrant-ssh).

Intermediary answered 23/11, 2018 at 10:35 Comment(1)
exactly what I was looking for 🙌Mayda
S
3

Ideally we just want to alter the vagrant ssh behaviour.

In my case, I wanted something that didn't affect any other processes in the environment, so we can do something like this in the vagrant file-

    VAGRANT_COMMAND = ARGV[0]
    if VAGRANT_COMMAND == "ssh"
        config.ssh.extra_args = ["-t", "cd /vagrant; bash --login"]
    end
Seaddon answered 2/2, 2020 at 1:21 Comment(0)
G
2

May be this can help. Edit the Vagrantfile as replace your username with vagrant

`
 config.vm.provision "shell" do |s|
 s.inline = <<-SHELL
 # Change directory automatically on ssh login
 if ! grep -qF "cd /home/vagrant/ansible" /home/vagrant/.bashrc ;
 then echo "cd    /home/vagrant/ansible" >> /home/vagrant/.bashrc ; fi
 chown vagrant. /home/vagrant/.bashrc
` 
Gotham answered 21/11, 2017 at 6:25 Comment(0)
A
0

You can use Ansible to assert that your .bashrc file contains cd /vagrant.

If you are not already using the Ansible provisioner for your VM, add the following lines to your Vagrantfile:

config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "provisioning/playbook.yml"
end

And in your playbook, add the following task/play:

---
- hosts: all
  gather_facts: no
  tasks:
  - name: chdir to vagrant directory
    ansible.builtin.lineinfile:
      path: /home/vagrant/.bashrc
      line: cd /vagrant

According to this Q&A, I would recommend to modify .bashrc instead of .profile or .bash_profile.

Alcaraz answered 10/7, 2022 at 8:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.