Przeczytaj i potwierdź skrypt powłoki przed rozpoczęciem przesyłania z curl do sh (curl -s [url] | sh)

11

Ilekroć muszę wykonać skrypt powłoki z sieci curl -s [url] | sh, najpierw otwieram się urlw przeglądarce, aby upewnić się, że skrypt nie jest złośliwy i można go bezpiecznie uruchomić.

Pamiętam, jak zobaczyłem sztuczkę z wiersza poleceń, która umożliwiła odczytanie skryptu z wiersza poleceń, a następnie potwierdzenie wykonania po przeczytaniu skryptu. Jeśli dobrze pamiętam, wyglądało to podobnie curl -s [url] | something...here | shi nie wymagało instalacji oprogramowania.

Czy ktoś zna tę sztuczkę?

Olivier Lalonde
źródło

Odpowiedzi:

5

Jest tak moreutilszwane narzędzie, vipektóre pokazuje stdin w edytorze, w którym możesz ujawnić i zmodyfikować plik, zanim zostanie on przekazany na standardowe wyjście.

Jeśli nie chcesz instalować moreutils, możesz osiągnąć coś podobnego:

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

mktempjest coreutilszainstalowany i prawdopodobnie jest już zainstalowany w twoim systemie.

Shawn J. Goff
źródło
2

Nie mogę wymyślić żadnego narzędzia, które zrobiłoby to, co opisujesz, ale łatwo jest zrobić ten fragment powłoki.

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

Zakłada się, że skrypt jest plikiem tekstowym. Puste bajty nie są obsługiwane: w zależności od powłoki mogą zostać usunięte lub mogą spowodować obcięcie linii lub całego pliku. Usuwane są również wszystkie znaki nowej linii na końcu pliku (konstrukcja heredoc dodaje jedną z powrotem). Zwykle nie stanowi to problemu dla skryptu, ale może być na przykład, jeśli skrypt kończy się archiwum w formacie binarnym, które wyodrębnia. Nie jest to bardzo niezawodny sposób dystrybucji pliku, ponieważ istnieje znaczne ryzyko błędnego zakodowania takiego skryptu binarnego. Niemniej jednak możesz sobie z tym poradzić, pisząc skrypt do pliku tymczasowego.

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- przestań być zły”
źródło
$()powinien być cytowany w pierwszym wierszu. Spowodowałoby to również usunięcie znaków NUL na wejściu, co może być fatalne (na przykład w przypadku skryptu samorozpakowującego się).
l0b0
1
@ l0b0 Nie musisz cytować w zadaniu, choć jest to prawdopodobnie dobry styl . Rzeczywiście utracono bajty zerowe, podobnie jak końcowe znaki nowej linii; jeśli zamierzasz dołączyć archiwum do skryptu powłoki, zalecamy użycie kodowania tekstu, takiego jak base64.
Gilles „SO- przestań być zły”
Wszystkie ważne punkty, jak zwykle. +1
l0b0
@ l0b0 Po zastanowieniu, choć jest to nieco podatne na ryzyko, jest to prawidłowy przypadek użycia. Zaktualizowałem swoją odpowiedź. Poprawiłem także wadę w mojej oryginalnej odpowiedzi, która nie pozwalała skryptowi na użycie standardowego wejścia (ponieważ skrypt został przekazany na standardowe wejście, bez wyraźnego powodu).
Gilles „SO- przestań być zły”
1

Trudno sobie wyobrazić, dlaczego w ogóle chcesz to zrobić, nie mówiąc już o tym, gdzie można znaleźć źródło (lub źródła) skryptów do pobrania i uruchamiania w ten sposób na tyle często, że potrzebuje specjalnego narzędzia.

Dlaczego nie wystarczy pobrać skrypt curl(lub wgetlub snarflub cokolwiek), bada i edytować go (jest to rzadka skrypt, który będzie potrzeby dostosowywania niektórych dla danego systemu), a następnie uruchomić go - przez co plik wykonywalny z chmodlub z sh scriptname?

cas
źródło
Nie chcę specjalnego narzędzia. Pamiętam, że był to łatwy sposób, używając standardowych narzędzi.
Olivier Lalonde,
2
Nie byłoby trudno napisać mały skrypt powłoki (prawdopodobnie tylko około 5 wierszy), aby pobrać skrypt, przedstawić go do przeglądania lesslub coś, a następnie zapytać, czy chcesz go uruchomić. Nie widzę, że byłoby to lepsze niż pobranie skryptu, przeglądanie go, a następnie uruchomienie, jeśli wydawałoby się, że jest OK. IMO byłoby gorzej, nie zapewniłoby to żadnych korzyści, ale usunęłoby elastyczność, jaką uzyskuje się po prostu pracując w powłoce.
cas
0

Użyj tego wiersza poleceń:

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

Możesz do tego użyć małej funkcji:

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

I użyj go w ten sposób:

curlsh http://site.in.net/path/to/script
Igor Chubin
źródło
0

Zakładając, że twój odczyt zna -p (monit), a skrypt nie musi być wykonywany za pomocą interpretera określonego przez shebang:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
nieznany użytkownik
źródło