A maneira mais fácil de copiar um único arquivo do host para o convidado do Vagrant?


241

Eu tenho um caso de uso em que ocasionalmente quero copiar um único arquivo da minha máquina host para o convidado do Vagrant.

Não quero fazer isso por meio de provisionadores tradicionais (Puppet / Chef), porque isso geralmente é único - só quero algo rápido para adicionar ao meu Vagrantfile.

Não quero compartilhar um diretório inteiro, possivelmente porque desejo substituir um arquivo existente sem colocar um diretório inteiro no convidado.

Também parece um pouco exagerado escrever um script de provisionamento de shell e lidar com possíveis escapes, quando tudo o que quero fazer é copiar um arquivo.

Então, qual é a maneira mais fácil de copiar um único arquivo do host para o convidado?


Note-se que a resposta aceita é baseada em Vagrant 1.x-- usando um provisioner arquivo é o padrão abordagem Vagrant 2 , embora mudando o ponto de montagem /vagrant como mencionado aqui também pode ser uma boa opção
STW

3
A resposta de @jouell realmente merece mais votos no caso de uso simples de uma cópia única de um único arquivo: vagrant upload /path/to/my/file...
dat

vagrant scp file.txt :~/.
AlikElzin-Kilaka

Respostas:


107

Em vez de usar um provisionador de shell para copiar o arquivo, você também pode usar um provisionador de arquivos Vagrant .

Nome do fornecedor: "file"

O fornecedor de arquivos permite fazer upload de um arquivo da máquina host para a máquina convidada.

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
end

3
Esta é definitivamente a melhor maneira de fazer isso no Vagrant 2! No entanto, Vagrant 2 não estava disponível no momento eu precisava fazer isso ... :)
LeeXGreen

4
Esta solução parece boa, mas não consigo copiar nenhum arquivo devido a erros de permissão.
orbatschow

@orbatschow Eu tive o mesmo problema, mas não se eu copiados-lo para/tmp
Ben

6
não foi isso que o OP pediu. a questão era como ocasionalmente transferir arquivos; ter que executar o provisionamento é um exagero.
AXD

253

Como você pede a maneira mais fácil, sugiro usar o vagrant-scp . Ele adiciona um comando scp ao vagrant, para que você possa copiar arquivos para sua VM como faria normalmente com o scp.

Instalar via:

vagrant plugin install vagrant-scp

Use-o assim:

vagrant scp <some_local_file_or_dir> [vm_name]:<somewhere_on_the_vm>

1
Isso não funcionou para mim. Eu instalei o plugin, mas continuava recebendo um erro que dizia: "O plugin" vagrant-scp "não foi encontrado. Verifique se ele está instalado corretamente via vagrant plugin."
Rockerston

6
Oi Rod, o vagrant-scp trabalha com o Vagrant 1.7+. No bug que você abriu, você está executando o 1.4.3. Se você precisar deste plug-in, receio que tenha que atualizar (o que é rápido e indolor).
Luca Invernizzi

1
Eu tentei este comando para copiar arquivos, mas não funcionou e, dando erro vagrant scp /vagrant/www/koushik.php ubuntu/trusty64:/usr/share/nginx/html, estou tentando copiar arquivos no diretório raiz do nginx. Diz: The machine with the name 'C' was not found configured for this Vagrant environment. O diretório e tudo está bem.
Koushik Das

3
Uma coisa a acrescentar: é necessário usar o ID da máquina que você pode obter com o status global vagante na primeira coluna. No entanto, esta é a melhor solução imho.
min hundje 7/03/2017

1
@KoushikDas Não funciona imediatamente na janela. Você precisa habilitar o subsistema Ubuntu no Windows 10 e, em vez de colocar C: / .. no caminho para o arquivo, insira / mnt / c / ... E funciona hooray! Observe também o outro comentário, use o status global vagrant para obter o ID da máquina vagrant.
Andrew

141

Na verdade, existe uma solução muito mais simples. Consulte https://gist.github.com/colindean/5213685/#comment-882885 :

"observe que, a menos que você queira especificamente o scp por algum motivo, a maneira mais fácil de transferir arquivos do host para a VM é apenas colocá-los no mesmo diretório que o Vagrantfile - esse diretório é automaticamente montado em / vagrant na VM, portanto você pode copiar ou usá-los diretamente da VM ".


3
É exatamente isso que minha resposta faz ... ele executa um provisionador de shell para copiar o arquivo de / vagrant /.
LeeXGreen

2
É melhor usar o provisionamento vagante como a LeexGreen usou.
Tokhi

4
Certifique-se que config.vm.synced_folder ".", "/vagrant", disabled: falsee depoisvagrant reload
Christopher Markieta

isso não funciona na centos/7caixa vagrant se você tentar fazer a operação reversa (caixa vagrant para a máquina local).
Ryan Tuck

Isso funciona perfeitamente para mim ao copiar um arquivo da minha VM vagrante do Ubuntu 14 para o meu host. Obrigado!!
XtraSimplicity

98

Por padrão, a primeira instância vagrant usa a porta ssh como 2222 e seu endereço IP é 127.0.0.1 (pode ser necessário ajustar a porta com o host virtual real)

==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)

Portanto, você pode executar o comando abaixo para copiar seu arquivo local para uma instância vagrant. senha é igual ao nome de usuário que é vagrant.

scp -P 2222 your_file vagrant@127.0.0.1:.

Você também pode copiar o arquivo de volta para o host local.

scp -P 2222 vagrant@127.0.0.1:/PATH/filename .

3
Eu tive que fazer isso e desabilitar a verificação estrita de chave:scp -P 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no my-file.txt matt@127.0.0.1:/tmp
Matt

Eu recomendarei adicionar essas opções ssh ~/.ssh/configcomo padrão, o que eu fiz no meu ambiente: #StrictHostKeyChecking no
BMW

1
+1 + Se alguém tem mais de um máquinas virtuais o valor do porto devem ser tomadas a partir da interface do usuário do Oracle VM VirtualBox Manager - selecione vm à esquerda, configurações de rede, o encaminhamento de porta
Yordan Georgiev

1
Isso é melhor que a resposta aceita. O diretório / vagrant nem sempre está lá.
precisa saber é o seguinte

Surpreendente quanto é mais difícil rsynctrabalhar neste caso em comparação com scp, dada a descrição do rsync como um "substituto mais rápido e flexível para o rcp".
Curinga

56

Aqui está minha abordagem para o problema:

Etapa 1 - Encontre a chave privada, porta ssh e IP:

root@vivi:/opt/boxes/jessie# vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /root/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Etapa 2 - Transfira o arquivo usando a porta e a chave privada como parâmetros para scp:

  scp -P 2222 -i /root/.vagrant.d/insecure_private_key \
  someFileName.txt vagrant@127.0.0.1:~

Espero que ajude,


4
Esta é a maneira mais simples. Obrigado.
Elmonkeylp

2
Usar a chave me permitiu transferir o arquivo. A resposta mais alta sem essas informações não funcionou, então obrigado!
Inostia

1
Solução fácil e completa.
Tao Starbow 15/07/19

27

O que acabei fazendo foi manter o arquivo dentro do meu diretório vagrant (montado automaticamente como / vagrant /) e copiá-lo com um provisionador de shell:

command = "cp #{File.join('/vagrant/', path_within_repo)} #{remote_file}"
config.vm.provision :shell, :inline => command

4
Eu recomendaria o uso de coreutils, installpor exemplo, install -D -m644 -C ...src dest. em vez de cp, porque você pode fazer coisas como especificar permissões, propriedade, criar automaticamente diretórios principais, apenas copiar se o arquivo precisar ser atualizado, etc ... em vez de cp, o que é simples e adequado necessário fazer.
Xenoterracide

@LeeXGreen. Estou tentando fazer a mesma coisa que você estava tentando fazer, mas não entendi sua resposta. Você digitou essa linha de código no terminal? Onde exatamente você colocou isso?
Dan Rubio

O snippet de código da minha resposta está no seu Vagrantfilelado de outros provedores. Você vai precisar para substituir path_within_repoe remote_filecom as coisas que fazem sentido, para a sua aplicação, é claro :)
LeeXGreen

Funciona, mas eu recebo o erro "padrão: stdin: não é um tty"
radtek


20

Se você não tiver os arquivos em seu diretório, poderá executar esse código em um arquivo de script na máquina Host.

#!/bin/sh
OPTIONS=`vagrant ssh-config | awk -v ORS=' ' '{print "-o " $1 "=" $2}'`

scp ${OPTIONS} /File/To/Copy vagrant@YourServer:/Where/To/Put/File

Nesta configuração, você só precisa alterar /File/To/Copypara o arquivo ou arquivos que deseja copiar e, em seguida, /Where/To/Put/Fileé o local na VM em que deseja que os arquivos sejam copiados.

Se você criar esse arquivo e chamá- copyToServer.shlo, poderá executar o shcomando para enviar esses arquivos por push.

sh ./copyToServer.sh

Como nota final, você não pode executar esse código como provisionerporque ele é executado no servidor Convidado, enquanto esse código é executado no Host.


1
Esta é provavelmente a melhor solução fora da instalação do plugin vagrant-scp. Ele usa a configuração SSH que o Vagrant usa para lidar com as diferentes configurações de rede fornecidas por diferentes provedores.
Sandy Chapman

1
Agradável! Sugiro que você também observe que as pessoas podem simplesmente pegar a saída vagrant ssh-confige colá-la em seu arquivo ~ / .ssh / config, para tornar isso ainda mais fácil no futuro. Ou seja, combinando isso com o CHF resposta
nealmcb

2
Eu achei necessário pular a primeira linha da saída ssh-config para evitar o erro "Diretiva de host não suportada como opção de linha de comando" - causada pelo cabeçalho da seção ssh-config: "Padrão do host". Portanto, meu script deve OPTIONS=`vagrant ssh-config | tail -n +2 | awk -v ORS=' ' '{print "-o " $1 "=" $2}'`omitir o uso dessa primeira linha de saída ssh-config.
troyfolger

1
Como alternativa, para remover o erro "Diretiva de host não suportada", você pode usar OPTIONS=`vagrant ssh-config | grep -v '^Host ' | awk -v ORS=' ' 'NF{print "-o " $1 "=" $2}'`como documentado aqui: gist.github.com/geedew/11289350
user783836

10

O Vagrant fornece uma maneira de executar um comando sobre ssh em vez de efetuar login, portanto, para host e convidado do Linux, você pode usar:

  • do host para o convidado:

cat ~/file_on_host.txt | vagrant ssh -c 'cat - > ~/file_on_guest.txt'

  • do convidado para o host:

vagrant ssh -c 'cat ~/file_on_guest.txt' > ~/file_on_host.txt

Não há necessidade de plugins ou recargas de convidados. Apenas certifique-se de fornecer o ID da caixa do vagrant ao 'vagrant ssh' se você não estiver no mesmo diretório que o arquivo Vagrant. Testado no Vagrant v1.8.1.


De convidado a abordagem anfitrião não preserva símbolos especiais em arquivos
Dr.X

9

Você pode adicionar entrada em ~/.ssh/config:

Host vagrant
    User vagrant
    HostName localhost
    Port 2222
    IdentityFile /home/user_name/.vagrant.d/insecure_private_key

e o simples scp file vagrant:/path/. Você pode encontrar o caminho para o arquivo de identidade usando o vagrant ssh-configcomando


1
Muito útil e ajuda a esclarecer o que está acontecendo. Isso permite copiar ambas as direções, fazer cópias recursiva, etc. e aproveita o conhecimento de scp / ssh existentes bem
nealmcb

1
Acabei de reler as respostas acima e descobri jogando com a resposta do geedew que vagrant ssh-configfornece uma configuração ainda mais completa e conveniente, que você pode colocar em ~ / .ssh / config. Mas obrigado novamente!
Nealmcb

7

Vá para o diretório em que você possui seu Vagrantfile
Em seguida, edite seu Vagrantfilee adicione o seguinte:

config.vm.synced_folder ".", "/vagrant", :mount_options => ['dmode=774','fmode=775']

"." significa que o diretório em que você está atualmente na máquina host
"/ vagrant" refere-se a "/ home / vagrant" na máquina convidada (máquina Vagrant).

Copie os arquivos que você precisa enviar para a máquina convidada na pasta onde você possui o seu. Vagrantfile Em seguida, abra o Git Bash e cdno diretório em que você possui Vagrantfilee digite:

vagrant scp config.json XXXXXXX:/home/vagrant/

onde XXXXXXX é o seu nome vm . Você pode obter seu nome de vm executando

vagrant global-status

7

se por algum motivo você não tiver permissão para usar

vagrant plugin install vagrant-scp

existe uma maneira alternativa:

Primeiro , vagueie o seu VagrantProject e depois escreva no terminal:

vagrant ssh-config

você terá informações sobre "HostName" e "Port" da sua máquina virtual.

Em alguns casos, você pode ter algumas máquinas virtuais em seu projeto. Portanto, basta encontrar sua máquina-mestre (em geral, esta VM possui a porta 2222) e não preste atenção às informações de outras máquinas.

escreva o comando para fazer a cópia:

scp -P xxPortxx  /Users/where/is/your/file.txt  vagrant@xxHostNamexx:/home/vagrant

Nesse íngreme, você terá que colocar uma senha vaga: por padrão, é "vaga"

depois disso, se você olhar para os arquivos em sua máquina virtual:

vagrant ssh xxVirtualMachineNamexx
pwd
ls

você terá o "arquivo.txt" no diretório da sua máquina virtual


depois de colocar a senha vagabundo Eu estou começando "Permissão negada"
user2568374

2
mas isso ocorreu devido a permissões no diretório de destino. Copiei para / home / vagrant e isso funcionou.
user2568374

4

O vagrant scp plugin funciona se você souber o nome da sua caixa vagrant. verifique o status global vagrante que fornecerá o nome da sua caixa e você poderá executar:

vagrant global-status
id       name    provider   state   directory
------------------------------------------------------------------------
13e680d  **default** virtualbox running /home/user

vagrant scp ~ / foobar "nome no meu caso padrão": / home / "user" /


1
isso funcionou para mim. a edição também é útil, também incluiria o comando para instalar o vagrant scp plugin.
precisa saber é o seguinte

1

Tente isso .. ubuntu 14.04 vagrant Isso funcionou para mim.

scp -r -P 2222 vagrant@localhost:/home .

1

Uma maneira alternativa de fazer isso sem instalar nada ( vagrant-scpetc.) Observe que o nome defaultprecisa ser usado como está, pois vagrant ssh-configemite isso.

vg_scp() {
  tmpfile=$(mktemp /tmp/vagrant-ssh-config.XXXX)
  vagrant ssh-config > $tmpfile
  scp -F $tmpfile "$@"
  rm $tmpfile
}

# Copy from local to remote
vg_scp somefile default:/tmp

# Copy from remote to local
vg_scp default:/tmp/somefile ./

# Copy a directory from remote to local
vg_scp -r default:/tmp ./tmp

A função não seria necessária se scp -F =(vagrant ssh-config) ...tivesse funcionado através de shells. Mas como isso não é suportado pelo Bash, precisamos recorrer a essa solução alternativa.


1

Se alguém quiser transferir arquivos do Windows host para vagrant, então esta solução funcionou para mim.

1. Make sure to install **winscp** on your windows system
2. run **vagrant up** command
3. run **vagrant ssh-config** command and note down below details
4. Enter Hostname, Port, Username: vagrant, Password: vagrant in winscp and select **SCP**, file protocol 
5. In most cases, hostname: 127.0.0.1, port: 2222, username: vagrant, password: vagrant.

Você deve poder ver diretórios em sua máquina vagrant.


-3

Melhor maneira de copiar o arquivo do local para o vagrant, Não há necessidade de escrever nenhum código ou qualquer coisa ou qualquer alteração na configuração. 1 - Abra o vagrant ( vagrant up ) 2 - abra o cygwin 3 - cygwin: vá para a pasta onde está o arquivo vagrant ou de onde você inicia o vagrant 4- ssh vagrant 5- agora ele funcionará como um sistema normal.


Um problema que descobri com essa abordagem: se o vagrant precisar configurar suas Adições de Convidado, o diretório / vagrant poderá não ser realmente montado quando o fornecedor de arquivos for executado.
Torenware Networks 15/03/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.