3

I gather this should work in bash:

source <(curl -s https://example.com/script.sh)

or

bash <(curl -s https://example.com/script.sh)

or

curl -s https://example.com/script.sh | source /dev/stdin

But it's not working for me. Downloading to a file, sourcing the file and then removing the file does work. I'm curious as to why none of the one liners are working though.

11
  • 1
    What do you mean, it doesn't work? Are you trying to execute this in a bash script or..?
    – Phorce
    Commented Jan 25, 2013 at 23:05
  • Do you get an error message of some kind?
    – nohillside
    Commented Jan 26, 2013 at 10:46
  • I want to put it in my ~/.bashrc, I've tried running it at a bash prompt too. No error message. Just the aliases within it aren't available, the bash completion of SSH hostnames it sets up doesn't work, etc.
    – rich
    Commented Jan 26, 2013 at 11:40
  • Of course there is no error message, as the -s switch puts curl into silent mode. Try running it with the -sS switch instead and see what failure message you get.
    – kopischke
    Commented Jan 26, 2013 at 22:59
  • There's nothing wrong with the curl. As in the original post, a three line separate download, source and then removal of the temporary file works.
    – rich
    Commented Jan 26, 2013 at 23:10

2 Answers 2

2

You are correct that your two first on-liners should be working according to bash process substitution semantics. In my testing (bash 3.2 on OS X 10.8.2), the second one does, while the first one does not.

In the case of your first one-liner, it looks like you may be running into one of the limitations of process substitution. Quoting the Wikipedia page on process substitution:

Process substitution has some limitations: the “files” created are not seekable, which means the process reading or writing to the file cannot perform random access; it must read or write once from start to finish. Programs that explicitly check the type of a file before opening it may refuse to work with process substitution, because the “file” resulting from process substitution is not a regular file.

– if source is a command that has difficulties with this (at least in bash 3.2), that would explain its failure to work with process substitution.

The second one-liner possibly just looks like it fails because it executes the code in a subshell rather than sourcing it. If you are expecting it to set aliases and functions, this won’t work, as these do not carry over to the parent shell when defined in a subshell.

The third one-liner doesn’t work because source does not process stdin – only files (see bash man page).

6
  • 1
    Well, it works ok for me (at least the second one) so I suspect something else being amiss for the asker.
    – nohillside
    Commented Jan 28, 2013 at 9:19
  • @patrix Yeah, that is difficult to diagnose without knowing what the sourced file is meant to do. Judging from the comment threads, it is meant to setup aliases and completion functions, which won’t carry over from a subshell, of course. Amended my wording to reflect that.
    – kopischke
    Commented Jan 28, 2013 at 9:52
  • I doubt it's that process substitution doesn't work given the accepted answer here: superuser.com/questions/255260/bash-source-from-url
    – rich
    Commented Jan 28, 2013 at 19:36
  • 1
    I strongly doubt that accepted answer has actually been tested. On my OS X box, cat <(curl http://url.tld/file.sh) outputs file contents, cp <(curl http://url.tld/file.sh) /new/dest copies the file, and source <(curl http://url.tld/file.sh) fails.
    – kopischke
    Commented Jan 28, 2013 at 20:34
  • … or maybe different bash versions’ source builtin react differently to being passed a file descriptor through process substitution (AFAIK Ubuntu has been using bash 4 since 2010). Rephrased my answer to narrow down the specifics.
    – kopischke
    Commented Jan 28, 2013 at 21:02
1

I don´t know what you like to do but if you like to download a script (or whatever) use.

curl -s -L https://example.com/script.sh -o script.sh

for more details see

man curl 

in terminal. -s silent, -L location of target including redirect to a new target, -o output file, if you don´t use it then curl uses the filename on the target (-o is often very useful).

To run the script use

./script.sh
5
  • I'm trying to source a downloaded script into my bash environment.
    – rich
    Commented Jan 26, 2013 at 8:24
  • As long, as you don´t answer what you had done and what you like to do noone can answer this. Have you downloaded it ? Have you got an error from curl ? If you downloaded the script as described above, make it executable using chmode +x FILENAME and copy it somewhere in your PATH sudo mv FILENAME /usr/local/bin then you can run it in terminal. Or whatelse you mean ??? Commented Jan 26, 2013 at 10:07
  • @nawi-at-mac The beauty of the <() construct is that you don't need to create a temporary file manually, so I understand why the asker wants to use it. But without additional information about the specific error/failure it will be difficult to answer the question.
    – nohillside
    Commented Jan 26, 2013 at 10:55
  • There is no error. It doesn't have to be executable to source it, nor does it have to be in the PATH.
    – rich
    Commented Jan 26, 2013 at 11:39
  • This answer is missing the point of OP’s question, which stated clearly that a download and source sequence works, but is asking why sourcing the code via process substitution does not work. Also note OP intends to source the code (run it in the current shell context), not execute it as a script (which happens in a subshell).
    – kopischke
    Commented Jan 28, 2013 at 8:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .