从 URL 执行 bash 脚本

Posted

技术标签:

【中文标题】从 URL 执行 bash 脚本【英文标题】:Execute bash script from URL 【发布时间】:2011-08-09 18:58:24 【问题描述】:

假设我在 URL“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 运行 shell 脚本的安全问题,但现在让我们忽略所有这些。

【问题讨论】:

如果您最终创建了一个临时文件,您可能应该使用 mktemp 而不是滚动您自己的解决方案 cmd &lt;&lt;foo 是大多数 shell 中的 heredoc 语法,可能不是您想要的。 【参考方案1】:

不直接执行脚本,先下载再执行

SOURCE='https://gist.githubusercontent.com/cci-emciftci/123123/raw/123123/sample.sh'

curl $SOURCE -o ./my_sample.sh
chmod +x my_sample.sh
./my_sample.sh

【讨论】:

【参考方案2】:

如果您希望脚本使用当前 shell 运行,无论它是什么,请使用:

$SHELL:-sh -c "$(wget -qO - http://mywebsite.com/myscript.txt)"

如果你有wget,或者:

$SHELL:-sh -c "$(curl -Ls http://mywebsite.com/myscript.txt)"

如果你有curl

如果脚本是交互式的,即它要求用户输入,此命令仍然有效。

注意:默认情况下,OpenWRT 有一个 wget 克隆,但没有 curl

【讨论】:

【参考方案3】:

对于 bash、Bourne shell 和 fish:

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

标志“-s”使 shell 从标准输入读取。

【讨论】:

这应该适用于大多数 shell,而接受的答案不适用于 fish,例如。 什么是arg1 arg2?。我可以打电话给curl -s http://server/path/script.sh | bash -s吗? @Nairum 是的,你可以不带arg1和arg2调用,它们是传递给script.sh的参数。如果 script.sh 需要参数才能执行,您可以添加任意数量的参数。有 2 个参数只是一个例子。【参考方案4】:
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:~$ 

【讨论】:

这完全是错误的。在发布之前测试你的脚本,不要伪造输出。【参考方案5】:

用途:

curl -s -L URL_TO_SCRIPT_HERE | bash

例如:

curl -s -L http://bitly/10hA8iC | bash

【讨论】:

【参考方案6】:

一些无人值守的脚本我使用如下命令:

sh -c "$(curl -fsSL &lt;URL&gt;)"

我建议避免直接从 URL 执行脚本。您应该确保 URL 是安全的并在执行之前检查脚本的内容,您可以在执行之前使用 SHA256 校验和来验证文件。

【讨论】:

【参考方案7】:

这种方式既好又传统:

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: $#

【讨论】:

【参考方案8】:

最好的方法是

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

@user77115 的回答略有变化

【讨论】:

【参考方案9】:

我经常用下面的就够了

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
$

【讨论】:

【参考方案10】:

只需结合 amra 和 user77115 的答案:

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

它执行 bbstart.sh 远程脚本,将 -v -v 选项传递给它。

【讨论】:

【参考方案11】:
source <(curl -s http://mywebsite.com/myscript.txt)

应该这样做。或者,不要对您的初始重定向进行重定向,即重定向标准输入; bash 需要一个文件名,无需重定向即可正常执行,&lt;(command) 语法提供了一个路径。

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

echo &lt;(cat /dev/null)的输出可能会更清楚

【讨论】:

谢谢,这清楚地说明了发生了什么。只是好奇,使用初始重定向有什么好处?我问是因为对于 RVM 安装,他们使用命令:bash &lt; &lt;(curl -s https://rvm.beginrescueend.com/install/rvm) 为什么不只是:bash &lt;(curl -s https://rvm.beginrescueend.com/install/rvm) 小提示:如果 wget 可用但 curl 不可用(例如在现有的 Ubuntu 桌面系统上),您可以将 wget -q http://mywebsite.com/myscript.txt -O - 替换为 curl -s http://mywebsite.com/myscript.txt 请注意,您不能将命令行参数传递给脚本。 bash will_not_work foobar &lt;(curl -s http://example.com/myscript.sh) 如果您拥有该脚本,则可以使用环境变量,如下所示:MYFLAG1=will_work bash MYFLAG2=foobar &lt;(curl -s http://example.com/myscript.sh) 它也适用于这样的管道:curl -s http://example.com/myscript.sh | MYFLAG1=will_work MYFLAG2=foobar bash 这当然要求您使用 MYFLAG1 和 MYFLAG2 而不是 $1 和 $2 $ sudo bash xxx) 出错:bash: /dev/fd/63: Bad file descriptor 第一个解决方案(使用源的那个)根本不起作用。第二个有点工作,但有其局限性。它正在子shell 中从URL 执行脚本。我在脚本中定义了一些我想在父级中使用的函数。有没有办法做到这一点?还是我运气不好,唯一的解决方案是将该脚本复制到一个临时文件中,然后获取它?【参考方案12】:

还有:

curl -sL https://.... | sudo bash -

【讨论】:

最后一条是什么意思? 来自 bash 手册页: A -- 表示选项结束并禁用进一步的选项处理。 -- 之后的任何参数都被视为文件名和参数。 - 的参数等价于--。【参考方案13】:

这是通过传递一些参数(arg1 arg2)来执行远程脚本的方法:

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

【讨论】:

这会破坏 stty :\ 如果您使用标准输入,请使用 bash &lt;(curl ... ) 【参考方案14】:

您也可以这样做:

wget -O - https://raw.github.com/luismartingil/commands/master/101_remote2local_wireshark.sh | bash

【讨论】:

【参考方案15】:

使用wget,这通常是默认系统安装的一部分:

bash <(wget -qO- http://mywebsite.com/myscript.txt)

【讨论】:

RTFM:gnu.org/software/wget/manual/wget.html。 ||| -q == --quiet == "关闭 Wget 的输出。" ||| -O- == --output-document=- == 如果使用'-'作为文件,文档将被打印到标准输出。【参考方案16】:

试试吧:

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

【讨论】:

以上是关于从 URL 执行 bash 脚本的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Cygwin 在 Jenkins 控制台上显示 bash 脚本执行

从执行 bash 脚本中清除历史记录中的最后一个 bash 命令

从 bash 脚本中通过 ssh 在远程主机上执行命令

从 Bash 脚本执行 GREP/CUT 命令时遇到问题

从网页(NGINX Web 服务器)调用时,PHP 脚本不会执行 bash 脚本 [关闭]

sh bash脚本运行循环以从文件中读取随机URL和用户代理,并使用cURL运行请求。这可以从任何系统运行