242

Say I have a file at the URL http://mywebsite.example/myscript.txt that contains a script:

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

And I'd like to run this script without first saving it to a file. How do I do this?

Now, I've seen the syntax:

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

But this doesn't seem to work like it would if I saved to a file and then executed. For example readline doesn't work, and the output is just:

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

Similarly, I've tried:

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

With the same results.

Originally I had a solution like:

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

But this seems sloppy, and I'd like a more elegant solution.

I'm aware of the security issues regarding running a shell script from a URL, but let's ignore all of that for right now.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Tristan
  • 2,617
  • 3
  • 15
  • 9

16 Answers16

292
source <(curl -s http://mywebsite.example/myscript.txt)

ought to do it. Alternately, leave off the initial redirection on yours, which is redirecting standard input; bash takes a filename to execute just fine without redirection, and <(command) syntax provides a path.

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

It may be clearer if you look at the output of echo <(cat /dev/null)

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • Thanks, this made it clear what was going on. Just curious, what is the advantage of using that initial redirection? I ask because for RVM installation, they use the command: `bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)` Why not just: `bash <(curl -s https://rvm.beginrescueend.com/install/rvm)` – Tristan Apr 20 '11 at 20:49
  • @Tristan: If they're running an interactive install script/program (commercial installer package, or an installer whuch also supports custom installation types), they can provide it default answers. – geekosaur Apr 20 '11 at 20:52
  • 4
    Small note: if wget is available but curl is not (e.g. on a stock Ubuntu desktop system), you can substitute `wget -q http://mywebsite.com/myscript.txt -O -` for `curl -s http://mywebsite.com/myscript.txt`). – Chiara Coetzee Aug 21 '12 at 22:47
  • 7
    Be aware that you can't pass command line arguments to your script. `bash will_not_work foobar <(curl -s http://example.com/myscript.sh)` If you own the script you can use environment variables instead like so: `MYFLAG1=will_work bash MYFLAG2=foobar <(curl -s http://example.com/myscript.sh)` and it also works with pipes like so: `curl -s http://example.com/myscript.sh | MYFLAG1=will_work MYFLAG2=foobar bash` This of course requires that you use MYFLAG1 and MYFLAG2 instead of $1 and $2 – Bruno Bronosky Mar 18 '13 at 18:07
  • 5
    $ sudo bash <(curl -s http://xxx) got error: bash: /dev/fd/63: Bad file descriptor – Yin Nov 09 '15 at 06:49
  • @Jake Just a guess, but can it be that you are running `bash` as root, but 'curl' as a standard user? I'm not sure if Linux splits up file descriptors based on user, or at least restricts them to the user that created them. – IQAndreas Nov 17 '15 at 09:25
  • @Jake Try running `su`, then while you are root, run the command without `sudo`. – IQAndreas Nov 17 '15 at 09:25
  • If the script you're downloading needs to change environment variables like the path, this won't work. Is there a way to do this that allows changing the environment variables in the executing environment? – B T Nov 17 '15 at 09:41
  • 3
    The first solution (the one using source) did not work at all. The second worked somewhat but has its limitations. It is executing the script from the URL in a subshell. I have some functions defined in the script that I would like to use in the parent. Is there anyway to achieve that? Or am I out of luck and the only solution is to copy that script in a temporary file and then source it? – Harsh Pandey Sep 16 '17 at 00:19
  • How can you send arguments to a file executed this way? – Camilo Sampedro Oct 18 '18 at 07:51
  • The source version affects the current session, which means if your remote script calls `exit` (e.g. for an error) then it will drop you out of your session. The bash version works better for this, and also allows environment variables to be set locally in the script without persisting. – Richard Oct 08 '19 at 08:16
113

This is the way to execute remote script with passing to it some arguments (arg1 arg2):

curl -s http://server/path/script.sh | bash /dev/stdin arg1 arg2
Anandi Das
  • 1,239
  • 1
  • 8
  • 2
74

For bash, Bourne shell and fish:

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

Flag "-s" makes shell read from stdin.

user77115
  • 5,517
  • 6
  • 37
  • 40
  • 2
    this should work in most shells, while the accepted answer does not work with *fish*, for example. – hoijui Jun 10 '19 at 11:36
  • 1
    What is `arg1 arg2`?. Can I call just `curl -s http://server/path/script.sh | bash -s`? – Nairum Jan 08 '21 at 17:42
  • @Nairum Yes, you can call without arg1 and arg2, which are parameters passed to script.sh. If script.sh requires parameters to be able to execute, you can add as many parameters as you like. Having 2 parameters is just an example. – user77115 Mar 15 '21 at 07:39
21

Use:

curl -s -L URL_TO_SCRIPT_HERE | bash

For example:

curl -s -L http://bitly/10hA8iC | bash
Bonifacio2
  • 3,405
  • 6
  • 34
  • 54
Katie MC
  • 319
  • 2
  • 3
16

Using wget, which is usually part of default system installation:

bash <(wget -qO- http://mywebsite.example/myscript.txt)
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
amra
  • 16,125
  • 7
  • 50
  • 47
  • RTFM: https://www.gnu.org/software/wget/manual/wget.html. ||| -q == --quiet == "Turn off Wget’s output." ||| -O- == --output-document=- == If ‘-’ is used as file, documents will be printed to standard output. – amra Nov 20 '17 at 11:26
13

You can also do this:

wget -O - https://raw.github.com/luismartingil/commands/master/101_remote2local_wireshark.sh | bash
luismartingil
  • 1,029
  • 11
  • 16
12

I often using the following is enough

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

But in a old system( kernel2.4 ), it encounter problems, and do the following can solve it, I tried many others, only the following works

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

Examples

$ 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'
$

The problem may cause by network slow, or bash version too old that can't handle network slow gracefully

However, the following solves the problem

$ 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
$
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Chinglin Wen
  • 149
  • 1
  • 3
12

The best way to do it is

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

which is a slight change of answer by @user77115

12

You can use curl and send it to bash like this:

bash <(curl -s http://mywebsite.example/myscript.txt)
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Random832
  • 37,415
  • 3
  • 44
  • 63
8

Also:

curl -sL https://.... | sudo bash -
Thomas Decaux
  • 21,738
  • 2
  • 113
  • 124
  • 5
    What dose the last strip mean? – towry Feb 23 '15 at 07:59
  • 2
    From the bash man page: A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments. An argument of - is equivalent to --. – Mingjiang Shi Jun 30 '15 at 08:59
4

Just combining amra and user77115's answers:

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

It executes the bbstart.sh distant script passing it the -v -v options.

ling
  • 9,545
  • 4
  • 52
  • 49
2

Is some unattended scripts I use the following command:

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

I recommend to avoid executing scripts directly from URLs. You should be sure the URL is safe and check the content of the script before executing, you can use a SHA256 checksum to validate the file before executing.

Mauricio Sánchez
  • 4,602
  • 1
  • 23
  • 15
2

instead of executing the script directly, first download it and then execute

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
emrcftci
  • 3,355
  • 3
  • 21
  • 35
1

This way is good and conventional:

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
  • 11
  • 1
1

If you want the script run using the current shell, regardless of what it is, use:

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

if you have wget, or:

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

if you have curl.

This command will still work if the script is interactive, i.e., it asks the user for input.

Note: OpenWRT has a wget clone but not curl, by default.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Ross Smith II
  • 11,799
  • 1
  • 38
  • 43
-4
bash | curl http://your.url.here/script.txt

actual example:

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


Oh, wow im alive


juan@juan-MS-7808:~$ 
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108