Eu tenho um * nix sem cabeça mínimo, que não possui nenhum utilitário de linha de comando para baixar arquivos (por exemplo, sem curl, wget, etc.). Eu só tenho festança.
Como posso baixar um arquivo?
Idealmente, eu gostaria de uma solução que funcionasse em uma ampla gama de * nix.
bash
command-line
web
Chris Snow
fonte
fonte
gawk
Respostas:
Se você tiver o bash 2.04 ou superior com o
/dev/tcp
pseudo-dispositivo ativado, poderá baixar um arquivo do próprio bash.Cole o seguinte código diretamente em um shell bash (você não precisa salvar o código em um arquivo para execução):
Em seguida, você pode executá-lo a partir do shell, da seguinte maneira:
Fonte: resposta da Moreaki atualizando e instalando pacotes através da linha de comando cygwin?
Atualização: conforme mencionado no comentário, a abordagem descrita acima é simplista:
read
will retira as barras invertidas e os espaços em branco à esquerda.$line
irá glob.fonte
while read
desse jeito, retira as barras invertidas e os espaços em branco à esquerda, e o Bash não consegue lidar com NUL bytes muito bem; portanto, os arquivos binários estão fora. E sem aspas$line
irá glob ... Nada disso eu vejo mencionado na resposta.Use lince.
É bastante comum para a maioria do Unix / Linux.
-dump: despeja o primeiro arquivo no stdout e sai
Ou netcat:
Ou telnet:
fonte
lynx -source
está mais perto de wgetAdaptado da resposta de Chris Snow Isso também pode lidar com arquivos de transferência binária
Você pode testar arquivos binários como este
fonte
cat
. Não tenho certeza se isso é trapaça (já que não é puramente o shell) ou uma solução agradável (já quecat
é uma ferramenta padrão, afinal). Mas @ 131, você pode adicionar uma observação sobre por que funciona melhor do que as outras soluções aqui.Tomando estritamente o " just Bash e nada mais ", aqui está uma adaptação das respostas anteriores ( @ Chris , @ 131 ) que não chama nenhum utilitário externo (nem mesmo o padrão), mas também funciona com arquivos binários:
Use com
download http://path/to/file > file
.Lidamos com NUL bytes com
read -d ''
. Ele lê até um byte NUL e retorna true se encontrou um, false se não encontrou. O Bash não pode manipular NUL bytes em cadeias de caracteres, portanto, quandoread
retorna com true, adicionamos o byte NUL manualmente ao imprimir e, quando retorna false, sabemos que não há mais bytes NUL e esse deve ser o último dado .Testado com o Bash 4.4 em arquivos com NULs no meio e terminando em zero, um ou dois NULs, e também com os binários
wget
ecurl
do Debian. Owget
binário de 373 kB levou cerca de 5,7 segundos para baixar. Uma velocidade de cerca de 65 kB / s ou um pouco mais que 512 kb / s.Em comparação, a solução de gato do @ 131 termina em menos de 0,1 s, ou quase cem vezes mais rápido. Não é muito surpreendente, realmente.
Isso é obviamente tolo, já que sem o uso de utilitários externos, não há muito o que fazer com o arquivo baixado, nem torná-lo executável.
fonte
echo
eprintf
como builtins (ele precisa de um embutidoprintf
para implementarprintf -v
)Se você possui este pacote libwww-perl
Você pode simplesmente usar:
fonte
lynx
solução, pois o Perl certamente tem mais chances de ser pré-instalado que o Lynx.Em vez disso, use o upload via SSH da sua máquina local
Uma caixa "mínimo sem cabeça * nix" significa que você provavelmente faz o SSH nela. Então você também pode usar o SSH para fazer o upload para ele. O que é funcionalmente equivalente ao download (de pacotes de software etc.), exceto quando você deseja que um comando de download inclua em um script no servidor sem cabeçalho, é claro.
Conforme mostrado nesta resposta , você executaria o seguinte em sua máquina local para colocar um arquivo em seu servidor sem controle remoto:
Upload mais rápido via SSH de uma terceira máquina
A desvantagem da solução acima, em comparação com o download, é a velocidade de transferência mais baixa, pois a conexão com a máquina local geralmente possui muito menos largura de banda do que a conexão entre o servidor sem cabeça e outros servidores.
Para resolver isso, é claro que você pode executar o comando acima em outro servidor com largura de banda decente. Para tornar isso mais confortável (evitando um login manual na terceira máquina), aqui está um comando para executar na sua máquina local .
Para garantir a segurança, copie e cole esse comando, incluindo o caractere de espaço inicial
' '
. Veja as explicações abaixo para o motivo.Explicações:
O comando ssh para sua terceira máquina
intermediate-host
, começará a baixar um arquivo para lá viawget
e comece a carregá-lo paratarget-host
via SSH. O download e o upload usam a largura de bandaintermediate-host
e acontecem ao mesmo tempo (devido aos equivalentes do canal Bash), portanto, o progresso será rápido.Ao usar isso, você deve substituir os dois logins do servidor (
user@*-host
), a senha do host de destino (yourpassword
), a URL de download (http://example.com/…
) e o caminho de saída no host de destino (/path/to/output-file.zip
) pelos valores próprios apropriados.Para as
-T -e none
opções de SSH ao usá-lo para transferir arquivos, consulte estas explicações detalhadas .Este comando destina-se a casos em que você não pode usar o mecanismo de autenticação de chave pública do SSH - ainda acontece com alguns provedores de hospedagem compartilhada, principalmente a Host Europe . Para automatizar ainda o processo, contamos com
sshpass
a capacidade de fornecer a senha no comando. Ele precisasshpass
ser instalado no seu host intermediário (sudo apt-get install sshpass
no Ubuntu).Tentamos usar de
sshpass
maneira segura, mas ainda não será tão seguro quanto o mecanismo pubkey SSH (dizman sshpass
). Em particular, fornecemos a senha SSH não como argumento de linha de comando, mas por meio de um arquivo que é substituído pela substituição do processo do bash para garantir que ela nunca exista no disco. Oprintf
é um bash embutido, certificando-se de que essa parte do código não apareça como um comando separado naps
saída, pois isso exporia a senha [ origem ]. Eu acho que esse uso desshpass
é tão seguro quanto asshpass -d<file-descriptor>
variante recomendadaman sshpass
, porque o bash o mapeia internamente para um/dev/fd/*
descritor de arquivo assim. E isso sem usar um arquivo temporário [ fonte] Mas não há garantias, talvez eu tenha esquecido alguma coisa.Novamente, para tornar o
sshpass
uso seguro, precisamos impedir que o comando seja gravado no histórico do bash em sua máquina local. Para isso, todo o comando é anexado com um caractere de espaço, que tem esse efeito.A
-o StrictHostKeyChecking=no
parte evita que o comando falhe, caso nunca se conecte ao host de destino. (Normalmente, o SSH aguardaria a entrada do usuário para confirmar a tentativa de conexão. Fazemos o procedimento de qualquer maneira.)sshpass
espera um comandossh
ouscp
como seu último argumento. Portanto, temos que reescrever owget -O - … | ssh …
comando típico em um formulário sem um pipe do bash, conforme explicado aqui .fonte
Com base na receita de Chris Snow. Fiz algumas melhorias:
Aqui está o código:
fonte
echo -en "GET ${PATH} HTTP/1.1\r\nHost: ${HOST}\r\n${tag}\r\n\r\n" >&3
,${tag}
não é especificada.tag
variável está correta, funciona bem agora.