Выполнить bash-скрипт из URL

184

Скажем, у меня есть файл по адресу «http://mywebsite.com/myscript.txt», который содержит скрипт:

#!/bin/bash
echo "Hello, world!"
read -p "What is your name? " name
echo "Hello, ${name}!"

И я хотел бы запустить этот скрипт без предварительного сохранения его в файл. Как мне это сделать?

Теперь я видел синтаксис:

bash < <(curl -s http://mywebsite.com/myscript.txt)

Но это, похоже, не работает, как если бы я сохранил в файл, а затем выполнить. Например, readline не работает, а вывод просто:

$ bash < <(curl -s http://mywebsite.com/myscript.txt)
Hello, world!

Точно так же я пробовал:

curl -s http://mywebsite.com/myscript.txt | bash -s --

С такими же результатами.

Первоначально у меня было решение как:

timestamp=`date +%Y%m%d%H%M%S`
curl -s http://mywebsite.com/myscript.txt -o /tmp/.myscript.${timestamp}.tmp
bash /tmp/.myscript.${timestamp}.tmp
rm -f /tmp/.myscript.${timestamp}.tmp

Но это кажется небрежным, и я хотел бы более элегантное решение.

Я знаю о проблемах безопасности, связанных с запуском сценария оболочки из URL-адреса, но давайте сейчас проигнорируем все это.

Тристан
источник
3
Если вы в конечном итоге создаете временный файл, вам, вероятно, следует использовать mktempвместо того, чтобы использовать собственное решение
Hasturkun,
cmd <<foo это синтаксис heredoc в большинстве оболочек и, вероятно, не то, что вы хотите.
dietbuddha

Ответы:

218
source <(curl -s http://mywebsite.com/myscript.txt)

должен сделать это. В качестве альтернативы, оставьте исходное перенаправление на вашем, которое перенаправляет стандартный ввод; bashберет имя файла для исполнения без переадресации, а <(command)синтаксис предоставляет путь.

bash <(curl -s http://mywebsite.com/myscript.txt)

Это может быть яснее, если вы посмотрите на вывод echo <(cat /dev/null)

geekosaur
источник
Спасибо, это дало понять, что происходит. Просто любопытно, в чем преимущество использования этого начального перенаправления? Я спрашиваю, потому что для установки RVM, они используют команду: bash < <(curl -s https://rvm.beginrescueend.com/install/rvm) Почему бы просто: bash <(curl -s https://rvm.beginrescueend.com/install/rvm)
Тристан
4
Небольшое замечание: если Wget доступен , но завиток не является (например , на складе настольной системы Ubuntu), вы можете заменить wget -q http://mywebsite.com/myscript.txt -O -на curl -s http://mywebsite.com/myscript.txt).
D Coetzee
5
Помните, что вы не можете передавать аргументы командной строки в ваш скрипт. bash will_not_work foobar <(curl -s http://example.com/myscript.sh)Если у вас есть сценарий, вы можете использовать вместо него переменные окружения, например, так: MYFLAG1=will_work bash MYFLAG2=foobar <(curl -s http://example.com/myscript.sh)он также работает с конвейерами следующим образом: curl -s http://example.com/myscript.sh | MYFLAG1=will_work MYFLAG2=foobar bashэто, конечно, требует, чтобы вы использовали MYFLAG1 и MYFLAG2 вместо 1 и 2 долларов США
Бруно Броноски
3
$ sudo bash <(curl -s xxx ) получил ошибку: bash: / dev / fd / 63: Неверный дескриптор файла
Джейк
2
Первое решение (использующее источник) не работало вообще. Второй работал несколько, но имеет свои ограничения. Он выполняет скрипт из URL в подоболочке. У меня есть некоторые функции, определенные в скрипте, которые я хотел бы использовать в родительском. Есть ли способ достичь этого? Или мне не повезло, и единственное решение - скопировать этот сценарий во временный файл и затем получить его?
Суровая Пандей
86

Это способ выполнения удаленного скрипта с передачей ему некоторых аргументов (arg1 arg2):

curl -s http://server/path/script.sh | bash /dev/stdin arg1 arg2
Ананди Дас
источник
2
это ломает stty: \ использовать, bash <(curl ... ) если вы используете stdin
Flores Robles
47

Для bash, Bourne shell и рыбы:

curl -s http://server/path/script.sh | bash -s arg1 arg2

Флаг "-s" делает чтение оболочки из стандартного ввода.

user77115
источник
1
это должно работать в большинстве оболочек, в то время как принятый ответ не работает , например, с рыбой .
Hoijui
16

Использование wget, которое обычно является частью установки системы по умолчанию:

bash <(wget -qO- http://mywebsite.com/myscript.txt)
Амра
источник
RTFM: gnu.org/software/wget/manual/wget.html . ||| -q == --quiet == "Отключить вывод Wget." ||| -O- == --output-document = - == Если в качестве файла используется '-', документы будут распечатаны на стандартный вывод.
amra
13

Использование:

curl -s -L URL_TO_SCRIPT_HERE | bash

Например:

curl -s -L http://bitly/10hA8iC | bash
Кэти MC
источник
12

Попробуйте просто:

bash <(curl -s http://mywebsite.com/myscript.txt)
Random832
источник
11

Вы также можете сделать это:

wget -O - https://raw.github.com/luismartingil/commands/master/101_remote2local_wireshark.sh | bash
luismartingil
источник
11

Лучший способ сделать это

curl http://domain/path/to/script.sh | bash -s arg1 arg2

это небольшое изменение ответа от @ user77115

Вамсидхар Муггулла
источник
6

Я часто использую следующее достаточно

curl -s http://mywebsite.com/myscript.txt | sh

Но в старой системе (kernel2.4), он сталкивается с проблемами, и решить эту проблему может следующее, я пробовал много других, только следующие работы

curl -s http://mywebsite.com/myscript.txt -o a.sh && sh a.sh && rm -f a.sh

Примеры

$ curl -s someurl | sh
Starting to insert crontab
sh: _name}.sh: command not found
sh: line 208: syntax error near unexpected token `then'
sh: line 208: ` -eq 0 ]]; then'
$

Проблема может быть вызвана медленной работой сети или слишком старой версией bash, которая не может корректно работать с сетью

Тем не менее, следующее решает проблему

$ curl -s someurl -o a.sh && sh a.sh && rm -f a.sh
Starting to insert crontab
Insert crontab entry is ok.
Insert crontab is done.
okay
$
Чинглин Вэнь
источник
4

Также:

curl -sL https://.... | sudo bash -
Томас Деко
источник
3
Какую дозу означает последняя полоска?
Towry
Со страницы руководства bash: A - сигнализирует об окончании параметров и отключает дальнейшую обработку параметров. Любые аргументы после - обрабатываются как имена файлов и аргументы. Аргумент - эквивалентен -.
Минцзян Ши
3

Просто объединяем ответы amra и user77115:

wget -qO- https://raw.githubusercontent.com/lingtalfi/TheScientist/master/_bb_autoload/bbstart.sh | bash -s -- -v -v

Он выполняет удаленный скрипт bbstart.sh, передавая ему параметры -v -v.

вереск
источник
2

В некоторых автоматических сценариях я использую следующую команду:

sh -c "$(curl -fsSL <URL>)"

Я рекомендую избегать выполнения скриптов непосредственно из URL. Вы должны быть уверены, что URL-адрес безопасен и проверить содержимое скрипта перед выполнением, вы можете использовать контрольную сумму SHA256 для проверки файла перед выполнением.

Маурисио Санчес
источник
0

Этот способ хорош и условен:

17:04:59@itqx|~
qx>source <(curl -Ls http://192.168.80.154/cent74/just4Test) Lord Jesus Loves YOU
Remote script test...
Param size: 4

---------
17:19:31@node7|/var/www/html/cent74
arch>cat just4Test
echo Remote script test...
echo Param size: $#
javafoot
источник
-3
bash | curl http://your.url.here/script.txt

фактический пример:

juan@juan-MS-7808:~$ bash | curl https://raw.githubusercontent.com/JPHACKER2k18/markwe/master/testapp.sh


Oh, wow im alive


juan@juan-MS-7808:~$ 
Случайные мемы 2k18
источник
Это прямо неправильно. Протестируйте свои сценарии перед публикацией и не подделывайте вывод.
Коркман