Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to run a script from URL as root with this command:

sudo bash <(curl -s http://copy.com/gLVZIqUubzcS/popcorn)

But I'm getting this error:

bash: /dev/fd/63: Aucun fichier ou dossier de ce type

French for "not found". Any ideas what it might be?

P.S: I'm running Ubuntu 12.04

share|improve this question

2 Answers 2

up vote 4 down vote accepted

Don't use process substitution like that. In practice, it's pretty much just this anyway:

sudo sh <<CURL_SCRIPT
    $(curl -s http://copy.com/gLVZIqUubzcS/popcorn)
CURL_SCRIPT

Or:

curl -s http://copy.com/gLVZIqUubzcS/popcorn | sudo sh

Unless the script you're trying to run makes use of bashisms the above will work. If it does use bash-only syntax you should do:

curl -s http://copy.com/gLVZIqUubzcS/popcorn | sudo . /dev/stdin

Though the above doesn't seem to work, which I expect is due to sudo not liking the shell's built-in .dot.

So do this:

curl -s http://copy.com/gLVZIqUubzcS/popcorn | sudo ${0#-} /dev/stdin

You could also simply do:

sudo sh -c "$(curl -s http://copy.com/gLVZIqUubzcS/popcorn)"

You don't need to invoke the bash executable again when you can use the shell's built-ins instead.

share|improve this answer
    
Many thanks! Actually the script does use much of bashisms. The last method actually worked but I have to adapt my script to sh. Thanks! –  pr.nizar Apr 15 at 7:36
1  
@pr.nizar the ${0#-} will work as well. –  mikeserv Apr 15 at 8:44
    
Thank you! Yep it does! Just one more question: how to pass an argument to the script with that: sudo bash -c "$(curl -s http://copy.com/gLVZIqUubzcS/popcorn)"? I can't figure it out! –  pr.nizar Apr 15 at 15:35
1  
@pri.nizar In that case you should use a function, and call its positionals after the script is fully loaded. Other wise you could stream in the definition on a separate file descriptor in a here-doc. Or save your params to a variable and call it afterward. Honestly, the possible solutions from my perspective are too numerous to enumerate, but that's mostly because I don't really know what you're doing. If you could specify? I'd be happy to visit any link you provide me. Perhaps in another question? Describe the workflow from start - finish and the purpose for it? And yes, that's how -c works. –  mikeserv Apr 16 at 14:12
1  
@pri.nizar - this is approaching other question territory, but if you need to pass arguments then you need to configure your script to handle parameters or environment variables, or to accept arguments over stdin. Understand that because you do not chmod +x a file you do not exec the script but rather a shell that sources your script. This is not a very serious limitation - all shell scripts are just interpreted text files anyway - but the process is initialized a little differently and so arg handling will differ. I think the pipe would work better than than -c though. –  mikeserv Apr 16 at 14:57

sudo closes all open file descriptors other than stdin, stdout and stderr (see man sudo) so process substitution does not work OOTB with sudo.

Compare

$ sudo bash <(echo echo foo)
bash: /dev/fd/63: No such file or directory

and

$ bash <(echo echo foo)
foo

You can work around this (or use the -C flag to sudo), but doing what you are trying to do is bad - albeit common - practice anyway. If you really just want to run the installer, get a root-shell first and then run the rest without sudo.

share|improve this answer
    
Many thanks man! But it says I'm not permitted to use the -C option. I think I'm doing it wrong.. To what number should I set the fd? –  pr.nizar Apr 15 at 7:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.