Cómo evitar que cURL escriba sobre archivos descargados

1

Estoy usando

$ xargs -n 1 curl -O < gwurls.txt

para obtener una larga lista de archivos. Por desgracia, el sitio que estoy agarrando a partir basa en la ruta de acceso para proporcionar singularidad, por lo que -Ono conoce la diferencia entre a/1.pdfy b/1.pdfy clobbers el archivo.

¿Hay una manera simple de evitar esto?

PHPeer
fuente

Respuestas:

0

Un par de enfoques:

  • Do umask 222(o umask 277, si su umask es actualmente 77; es decir, agregue 200 a su umask). Esto hará que todos los archivos que cree estén protegidos r--(lo que sea) en lugar de rw-(lo que sea) , por lo que, una vez que haya creado un archivo, no podrá sobrescribirlo sin chmodcrearlo primero (a menos que esté ejecutando como raíz). Esto responde la pregunta que planteó en su título, pero en realidad no resuelve su problema; solo significa que descargará y retendrá a/1.pdfy se perderá con éxito, en b/1.pdflugar de al revés. (Si te sirve de consuelo, recibirás mensajes de error que te alertarán sobre las colisiones).
  • El problema parece estar en su gwurls.txtarchivo, que ingenuamente enumera ambos a/1.pdf y b/1.pdf, por lo tanto , intente solucionarlo allí. Destrozarlo sedo algo parecido
  a / 1.pdf a_1.pdf
  b / 1.pdf b_1.pdf

... y luego escribe un script que se ejecuta curlcon una URL de $1y una especificación de salida de $2, y ejecuta

  xargs -n 2su_script< modified_gwurls.txt

entonces xargscorrerá

your_script   a/1.pdf  a_1.pdf
your_script  b/1.pdf  b_1.pdf

Esto se vuelve complicado si alguno de los nombres de archivo tiene espacios en blanco, pero supongo que eso no es posible para las URL, ¿verdad?

Scott
fuente
Estaba completamente enfocado en la llamada de rizo y evité lo obvio, que estaba modificando el raspado. Gracias por la perspectiva
PHPeer
0

Wget

La solución más sencilla sería instalar Wget y ejecutar el siguiente comando:

wget --input-file=gwurls.txt

Wget cambia automáticamente el nombre del archivo de salida si ya existe un archivo con el mismo nombre.

Renombrar

Si elimina el esquema y el host (p. Ej., http://example.com/) De la URL, puede reemplazar todas las barras con guiones bajos (o cualquier otro carácter) y guardar los archivos así. Para estar seguro, puede reemplazar los guiones bajos preexistentes por guiones bajos dobles.

Con bash, esto debería funcionar:

while read -r URL; do
    OUTPUT="${URL#http://example.com/}"
    OUTPUT="${OUTPUT//_/__}"
    OUTPUT="${OUTPUT//\//_}"

    curl --output "$OUTPUT" --url "$URL"
done < gwurls.txt

Cómo funciona:

  • while read -r URL; do ... done < gwurls.txtlee el contenido de gwurls.txt línea por línea y almacena la línea completa (sin espacios iniciales o finales) en la URL variable y se ejecuta ....

  • Los tres OUTPUT=...comandos realizan los reemplazos mencionados utilizando la manipulación de cadenas bash .

  • curl --output "$OUTPUT" --url "URL" descarga el archivo y lo almacena con el nombre de archivo deseado.

Estructura de directorios

También es posible volver a crear la estructura de directorios del servidor utilizando un enfoque similar.

Con bash, esto debería funcionar:

while read -r URL; do
    OUTPUT="${URL#http://example.com/}"

    curl --create-dirs --output "$OUTPUT" --url "$URL"
done < gwurls.txt

Aquí, el --create-dirsmodificador hace que cURL cree el directorio asi se lee OUTPUTa/1.pdf .

Dennis
fuente
De acuerdo, wget habría sido el mejor enfoque, pero necesitaba una solución curl. Es curioso por qué cURL no tiene renombrado automático incorporado.
PHPeer