Прочитайте та підтвердьте скрипт оболонки перед тим, як переходити з curl до sh (curl -s [url] | sh)


11

Щоразу, коли мені доводиться виконувати сценарій оболонки з Інтернету curl -s [url] | sh, я спочатку відкриваю urlсвій веб-браузер, щоб переконатися, що скрипт не є шкідливим і безпечним для запуску.

Я пам’ятаю, що бачив трюк командного рядка, завдяки якому можна було прочитати скрипт із командного рядка та підтвердити виконання після прочитання сценарію. Якщо я пригадую правильно, це виглядало приблизно так curl -s [url] | something...here | shі не потребувало встановлення програмного забезпечення.

Хтось знає цю хитрість?

Відповіді:


5

Існує утиліта, що moreutilsназивається, vipeщо показує stdin в редакторі, де ви можете переглядати та змінювати файл, перш ніж він перейде до stdout.

Якщо ви не хочете встановлювати moreutils, ви можете виконати щось подібне:

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

mktempзнаходиться в coreutilsі, швидше за все, вже встановлено у вашій системі.


2

Я не можу придумати жодної утиліти, яка б зробила те, що ви описуєте, але досить просто зробити фрагмент оболонки.

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

Це передбачає, що сценарій є текстовим файлом. Нульові байти не підтримуються: залежно від оболонки вони можуть бути видалені або можуть спричинити врізання рядка або всього файлу. Також всі нові рядки в кінці файлу видаляються (конструкція heredoc додає одну задню частину). Зазвичай це не є проблемою для сценарію, але це може бути, наприклад, якщо сценарій закінчується архівом у двійковому форматі, який він витягує. Це не дуже надійний спосіб розповсюдження файлу, оскільки існує значний ризик неправильного кодування такого бінарного сценарію в якийсь момент. Тим не менш, ви можете впоратися з цим, записавши сценарій у тимчасовий файл.

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"

$()слід котирувати в першому рядку. Крім того, це видалить символи NUL у вхідних даних, що може бути фатальним (наприклад, у випадку саморозпаковування сценарію).
l0b0

1
@ l0b0 Не потрібно цитувати у завданні, хоча це, мабуть, хороший стиль . Нульові байти дійсно втрачаються, як і остаточні нові рядки; якщо ви збираєтеся включити архів до сценарію оболонки, рекомендую використовувати текстове кодування, наприклад base64.
Жил "ТАК - перестань бути злим"

Усі дійсні бали, як завжди. +1
l0b0

@ l0b0 Щодо другої думки, хоча це дещо схильне до ризику, це дійсний випадок використання. Я оновив свою відповідь. Я також виправив дефект моєї оригінальної відповіді, який не дозволив скрипту використовувати його stdin (оскільки сценарій був переданий на stdin без поважних причин).
Жил "ТАК - перестань бути злим"

1

Важко уявити, чому ви навіть хотіли б це зробити, не кажучи вже про те, де ви знайдете джерело (або джерела) сценаріїв для завантаження та запуску так часто, що для цього потрібен інструмент спеціального призначення.

Чому б просто не завантажити скрипт з curl(або wgetабо snarfбудь-яким іншим), вивчити його та відредагувати (це рідкісний сценарій, який не потребує певної настройки для вашої конкретної системи), а потім запустити його - або зробивши його виконуваним за допомогою chmodабо з sh scriptname?


Я не хочу спеціального інструменту. Пам’ятаю, був простий спосіб зробити це за допомогою стандартних інструментів.
Олів'є Лалонде

2
Не важко буде написати невеликий скрипт оболонки (мабуть, лише 5 або близько рядків), щоб завантажити скрипт, представити його для перегляду з lessчимось іншим, а потім запитати, чи хочете ви його запустити. Я не бачу, що це було б краще, ніж просто завантажити сценарій, переглянути його та запустити його, якщо це здалося б нормальним. IMO, це було б гірше, це не дало б жодної переваги, але позбавило б гнучкості, яку ви отримаєте від простої роботи в своїй оболонці.
cas

0

Використовуйте цей командний рядок:

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

Ви можете використовувати для цього невелику функцію:

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

І чим використовувати його таким чином:

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

0

Якщо припустимо, що ваш читання знає -p (підказка), і сценарій не повинен виконуватися за допомогою інтерпретатора, визначеного шебангом:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.