Leggere e confermare lo script della shell prima di eseguire il piping da curl a sh (curl -s [url] | sh)


11

Ogni volta che devo eseguire uno script di shell dal Web curl -s [url] | sh, per prima cosa apro urlnel mio browser Web per assicurarmi che lo script non sia dannoso e sia sicuro da eseguire.

Ricordo di aver visto un trucco da riga di comando che rendeva possibile leggere lo script dalla riga di comando e quindi confermare l'esecuzione dopo aver letto lo script. Se ricordo bene, sembrava qualcosa di simile curl -s [url] | something...here | she non richiedeva l'installazione di software.

Qualcuno conosce questo trucco?

Risposte:


5

Esiste un'utilità moreutilschiamata in vipecui viene mostrato stdin in un editor, in cui è possibile visualizzare e modificare il file prima che venga passato a stdout.

Se non vuoi installare moreutils, puoi realizzare qualcosa di simile in questo modo:

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

mktempè dentro coreutilsed è molto probabilmente già installato sul tuo sistema.


2

Non riesco a pensare a un'unica utility che farebbe quello che descrivi, ma è abbastanza facile trasformarlo in uno snippet di 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

Ciò presuppone che lo script sia un file di testo. I byte null non sono supportati: a seconda della shell, potrebbero essere rimossi o potrebbero causare il troncamento di una riga o dell'intero file. Inoltre vengono rimosse tutte le nuove righe alla fine del file (il costrutto ereditario ne aggiunge uno indietro). Questo non è normalmente un problema per uno script, ma potrebbe essere, ad esempio, se lo script termina con un archivio in formato binario che estrae. Questo non è un modo molto affidabile di distribuire un file in quanto esiste un rischio significativo che uno script binario di questo tipo venga erroneamente codificato a un certo punto. Tuttavia, puoi gestirlo scrivendo lo script in un file temporaneo.

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"

$()dovrebbe essere citato nella prima riga. Inoltre, questo rimuoverebbe i caratteri NUL nell'input, che potrebbe essere potenzialmente fatale (ad esempio nel caso di uno script autoestraente).
10

1
@ l0b0 Non è necessario citare un compito, anche se è probabilmente un buon stile . I byte null sono effettivamente persi, così come le newline finali; se hai intenzione di includere un archivio in uno script di shell, ti consiglio di usare una codifica di testo come base64.
Gilles 'SO- smetti di essere malvagio' il

Tutti i punti validi, come al solito. +1
l0b0

@ l0b0 Ripensandoci, sebbene sia un po 'soggetto a rischi, questo è un caso d'uso valido. Ho aggiornato la mia risposta. Ho anche corretto un difetto nella mia risposta originale che non permetteva allo script di usare il suo stdin (perché lo script è stato passato allo stdin, senza una buona ragione).
Gilles 'SO- smetti di essere malvagio' il

1

È difficile immaginare perché vorresti persino farlo, figuriamoci dove troverai una fonte (o fonti) di script da scaricare ed eseguire in questo modo abbastanza frequentemente da aver bisogno di uno strumento speciale.

Perché non scaricare semplicemente lo script con curl(o wgeto snarfqualsiasi altra cosa), esaminarlo e modificarlo (è uno script raro che non avrà bisogno di personalizzazioni per il tuo particolare sistema) e quindi eseguirlo - rendendolo eseguibile con chmodo con sh scriptname?


Non voglio uno strumento speciale. Ricordo che c'era un modo semplice per farlo con strumenti standard.
Olivier Lalonde il

2
Non sarebbe difficile scrivere un piccolo script di shell (probabilmente solo circa 5 righe) per scaricare uno script, presentarlo per la visualizzazione con lesso qualcosa del genere, e quindi chiederti se si desidera eseguirlo. Non riesco a vedere che sarebbe meglio che scaricare semplicemente lo script, visualizzarlo e quindi eseguirlo se sembrava OK. IMO sarebbe peggio, non offrirebbe alcun vantaggio ma eliminerebbe la flessibilità che si ottiene semplicemente lavorando nella shell.
Cas

0

Usa questa riga di comando:

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

È possibile utilizzare una piccola funzione per questo:

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

E che usarlo in questo modo:

curlsh http://site.in.net/path/to/script

0

Supponendo che la tua lettura sappia -p (prompt), e lo script non deve essere eseguito con l'interprete, specificato da shebang:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.