【问题标题】:Execute bash script from URL从 URL 执行 bash 脚本
【发布时间】: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 语法,可能不是您想要的。

标签: linux bash curl


【解决方案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)
                    

                    【讨论】:

                      猜你喜欢
                      • 2023-03-06
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-11-08
                      • 1970-01-01
                      相关资源
                      最近更新 更多