Lea y confirme el script de shell antes de pasar de curl a sh (curl -s [url] | sh)

11

Cada vez que tengo que ejecutar un script de shell desde la web curl -s [url] | sh, primero abro urlen mi navegador web para asegurarme de que el script no sea malicioso y sea seguro de ejecutar.

Recuerdo haber visto un truco en la línea de comandos que hizo posible leer el script desde la línea de comando y luego confirmar la ejecución después de leer el script. Si recuerdo correctamente, se veía algo así curl -s [url] | something...here | shy no requería ninguna instalación de software.

¿Alguien sabe este truco?

Olivier Lalonde
fuente

Respuestas:

5

Hay una utilidad moreutilsllamada vipeque muestra stdin en un editor, donde puede revew y modificar el archivo antes de que pase a stdout.

Si no desea instalar moreutils, puede lograr algo similar de esta manera:

file=$(mktemp); curl -s "$url" > $file; $EDITOR $file; sh $file; rm $file

mktempestá dentro coreutilsy es muy probable que ya esté instalado en su sistema.

Shawn J. Goff
fuente
2

No puedo pensar en una sola utilidad que haga lo que usted describe, pero es bastante fácil convertirlo en un fragmento de shell.

script=$(curl -s "$url")
printf "%s\nDo you want to run this script? [yN]" "$script"
read line
case $line in
  [Yy]|[Yy][Ee][Ss]) sh -c "$script";;
esac

Esto supone que el script es un archivo de texto. Los bytes nulos no son compatibles: dependiendo del shell, pueden eliminarse o pueden hacer que una línea o todo el archivo se trunque. También se eliminan todas las líneas nuevas al final del archivo (la construcción heredoc agrega una de nuevo). Esto normalmente no es un problema para un script, pero podría ser, por ejemplo, si el script termina con un archivo en formato binario que extrae. Esta no es una forma muy confiable de distribuir un archivo, ya que existe un riesgo significativo de que tal script binario se codifique erróneamente en algún momento. No obstante, puede manejarlo escribiendo el script en un archivo temporal.

script_file=$(mktemp)
curl -s "$url" | tee "$script_file"
printf "Do you want to run this script? [yN]"
read line
case $line in
  [Yy]|[Yy][Ee][Ss]) sh "$script_file";;
esac
rm "$script_file"
Gilles 'SO- deja de ser malvado'
fuente
$()debe ser citado en la primera línea. Además, esto eliminaría los caracteres NUL en la entrada, lo que podría ser fatal (por ejemplo, en el caso de un script autoextraíble).
l0b0
1
@ l0b0 No necesita citar en una tarea, aunque podría decirse que es un buen estilo . Los bytes nulos se pierden, al igual que las nuevas líneas finales; Si va a incluir un archivo en un script de shell, le recomiendo usar una codificación de texto como base64.
Gilles 'SO- deja de ser malvado'
Todos los puntos válidos, como siempre. +1
l0b0
@ l0b0 Pensándolo bien, aunque es algo propenso al riesgo, este es un caso de uso válido. He actualizado mi respuesta. También he corregido un defecto en mi respuesta original que no permitía que el script usara su stdin (porque el script se pasó en stdin, sin ninguna buena razón).
Gilles 'SO- deja de ser malvado'
1

Es difícil imaginar por qué incluso querrías hacer esto, y mucho menos dónde encontrarías una fuente (o fuentes) de scripts para descargar y ejecutar de esta manera con la frecuencia suficiente para que necesite una herramienta especial.

¿Por qué no simplemente descargar el script con curl(o wgeto snarfo lo que sea), examinarlo y editarlo (es un script raro que no necesitará alguna personalización para su sistema en particular) y luego ejecutarlo, ya sea haciéndolo ejecutable con chmodo con sh scriptname?

cas
fuente
No quiero una herramienta especial. Recuerdo que había una manera fácil de hacer esto con herramientas estándar.
Olivier Lalonde
2
No sería difícil escribir un pequeño script de shell (probablemente solo 5 o más líneas) para descargar un script, presentarlo para verlo lesso algo así y luego preguntarle si desea ejecutarlo. No puedo ver que eso sea mejor que simplemente descargar el script, verlo y luego ejecutarlo si me parece bien. En mi opinión, sería peor, no ofrecería ninguna ventaja, pero eliminaría la flexibilidad que obtienes de solo trabajar en tu shell.
cas
0

Use esta línea de comando:

curl URL | ( cat > /tmp/file; read REPLY; [[ ! $REPLY =~ ^[Yy]$ ]] && cat /tmp/file ) | sh

Podría usar una pequeña función para eso:

curlsh()
{
    curl "$1" \
    | ( cat > /tmp/file;read REPLY; [[ ! $REPLY =~ ^[Yy]$ ]] && cat /tmp/file ) \
    | sh
}

Y luego usarlo de esta manera:

curlsh http://site.in.net/path/to/script
Igor Chubin
fuente
0

Suponiendo que su lectura sabe -p (solicitud), y el script no necesita ejecutarse con el intérprete, especificado por shebang:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
usuario desconocido
fuente