Tengo un mínimo * sin cabeza * nix que no tiene ninguna utilidad de línea de comandos para descargar archivos (por ejemplo, sin curl, wget, etc.). Solo tengo bash.
¿Cómo puedo descargar un archivo?
Idealmente, me gustaría una solución que funcione en una amplia gama de * nix.
bash
command-line
web
Chris Snow
fuente
fuente
gawk
Respuestas:
Si tiene bash 2.04 o superior con el
/dev/tcp
pseudodispositivo habilitado, puede descargar un archivo de bash.Pegue el siguiente código directamente en un shell bash (no necesita guardar el código en un archivo para ejecutarlo):
Luego puede ejecutarlo desde el shell de la siguiente manera:
Fuente: ¿ Respuesta de Moreaki actualizando e instalando paquetes a través de la línea de comando cygwin?
Actualización: como se menciona en el comentario, el enfoque descrito anteriormente es simplista:
read
voluntad destruye las barras invertidas y los espacios en blanco iniciales.$line
será glob.fuente
while read
así, las barras invertidas y los espacios en blanco iniciales y Bash no pueden manejar muy bien los bytes NUL, por lo que los archivos binarios están fuera. Y sin comillas$line
se glob ... Nada de esto veo mencionado en la respuesta.Usa lince.
Es bastante común para la mayoría de Unix / Linux.
-dump: volcar el primer archivo a stdout y salir
O netcat:
O telnet:
fuente
lynx -source
está más cerca de wgetAdaptado de la respuesta de Chris Snow Esto también puede manejar archivos de transferencia binarios
Puedes probar archivos binarios como este
fuente
cat
. No estoy seguro de si eso es trampa (ya que no es puramente el shell), o una buena solución (ya quecat
es una herramienta estándar, después de todo). Pero @ 131, es posible que desee agregar una nota sobre por qué funciona mejor que las otras soluciones aquí.Tomando el " solo Bash y nada más " estrictamente, aquí hay una adaptación de respuestas anteriores ( @ Chris's , @ 131's ) que no llama a ninguna utilidad externa (ni siquiera estándar) pero también funciona con archivos binarios:
Usar con
download http://path/to/file > file
.Nos ocupamos de bytes NUL con
read -d ''
. Se lee hasta un byte NUL y devuelve verdadero si lo encontró, falso si no lo encontró. Bash no puede manejar bytes NUL en cadenas, por lo que cuandoread
regresa con verdadero, agregamos el byte NUL manualmente al imprimir, y cuando devuelve falso, sabemos que ya no hay bytes NUL, y este debería ser el último dato. .Probado con Bash 4.4 en archivos con NUL en el medio, y que termina en cero, uno o dos NUL, y también con los binarios
wget
ycurl
de Debian. Elwget
binario de 373 kB tardó aproximadamente 5,7 segundos en descargarse. Una velocidad de aproximadamente 65 kB / so un poco más de 512 kb / s.En comparación, la solución cat de @ 131 termina en menos de 0.1 s, o casi cien veces más rápido. No es muy sorprendente, de verdad.
Esto es obviamente una tontería, ya que sin usar utilidades externas, no hay mucho que podamos hacer con el archivo descargado, ni siquiera hacerlo ejecutable.
fuente
echo
yprintf
como incorporado (necesita un incorporadoprintf
para implementarprintf -v
)Si tiene este paquete libwww-perl
Simplemente puede usar:
fuente
lynx
solución, ya que es más probable que Perl esté preinstalado que Lynx.Utilice la carga en su lugar, a través de SSH desde su máquina local
Un cuadro "mínimo sin cabeza * nix" significa que probablemente se SSH en él. Por lo tanto, también puede usar SSH para cargarlo . Que es funcionalmente equivalente a la descarga (de paquetes de software, etc.), excepto cuando desea que se incluya un comando de descarga en un script en su servidor sin cabeza, por supuesto.
Como se muestra en esta respuesta , ejecutaría lo siguiente en su máquina local para colocar un archivo en su servidor remoto sin cabeza:
Carga más rápida a través de SSH desde una tercera máquina
La desventaja de la solución anterior en comparación con la descarga es una velocidad de transferencia más baja, ya que la conexión con su máquina local generalmente tiene mucho menos ancho de banda que la conexión entre su servidor sin cabeza y otros servidores.
Para resolver eso, por supuesto, puede ejecutar el comando anterior en otro servidor con un ancho de banda decente. Para hacerlo más cómodo (evitando un inicio de sesión manual en la tercera máquina), aquí hay un comando para ejecutar en su máquina local .
Para estar seguro, copie y pegue ese comando, incluido el carácter de espacio inicial
' '
. Consulte las explicaciones a continuación para conocer el motivo.Explicaciones:
El comando enviará ssh a su tercera máquina
intermediate-host
, comenzará a descargar un archivo allí a través dewget
y comenzará a cargarlo atarget-host
través de SSH. La descarga y la carga utilizan el ancho de banda de suintermediate-host
y suceden al mismo tiempo (debido a los equivalentes de la tubería Bash), por lo que el progreso será rápido.Al usar esto, debe reemplazar los dos inicios de sesión del servidor (
user@*-host
), la contraseña del host de destino (yourpassword
), la URL de descarga (http://example.com/…
) y la ruta de salida en su host de destino (/path/to/output-file.zip
) con los valores propios apropiados.Para conocer las
-T -e none
opciones de SSH al usarlo para transferir archivos, consulte estas explicaciones detalladas .Este comando está destinado a casos en los que no puede utilizar el mecanismo de autenticación de clave pública de SSH; todavía ocurre con algunos proveedores de alojamiento compartido, especialmente Host Europe . Para automatizar aún el proceso, confiamos en
sshpass
poder proporcionar la contraseña en el comando. Requieresshpass
estar instalado en su host intermedio (sudo apt-get install sshpass
en Ubuntu).Intentamos usarlo
sshpass
de forma segura, pero aún no será tan seguro como el mecanismo SSH pubkey (diceman sshpass
). En particular, proporcionamos la contraseña SSH no como un argumento de línea de comando sino a través de un archivo, que se reemplaza por la sustitución del proceso bash para asegurarnos de que nunca exista en el disco. Elprintf
es un bash incorporado, asegurándose de que esta parte del código no aparezca como un comando separado en laps
salida, ya que eso expondría la contraseña [ fuente ]. Yo creo que este uso desshpass
es tan segura como lasshpass -d<file-descriptor>
variante recomendada enman sshpass
, debido fiesta de la asigna internamente a un tal/dev/fd/*
descriptor de archivo de todos modos. Y eso sin usar un archivo temporal [ fuente] Pero no hay garantías, tal vez pasé por alto algo.Nuevamente para que el
sshpass
uso sea seguro, debemos evitar que el comando se grabe en el historial de bash en su máquina local. Para eso, todo el comando se antepone con un carácter de espacio, que tiene este efecto.La
-o StrictHostKeyChecking=no
parte evita que el comando falle en caso de que nunca se conecte al host de destino. (Normalmente, SSH esperaría la entrada del usuario para confirmar el intento de conexión. De todos modos, hacemos que continúe).sshpass
espera un comandossh
oscp
como último argumento. Entonces, tenemos que reescribir elwget -O - … | ssh …
comando típico en un formulario sin una tubería bash, como se explica aquí .fuente
Basado en la receta @Chris Snow. Hice algunas mejoras:
Aquí está el código:
fuente
echo -en "GET ${PATH} HTTP/1.1\r\nHost: ${HOST}\r\n${tag}\r\n\r\n" >&3
,${tag}
no se especifica.tag
variable es el conjunto correcto, funciona bien ahora.