用“读取”将脚本管道化为bash


10

我需要通过管道它运行一个脚本bashwget(而不是直接使用bash运行它)。

$ wget -O - http://example.com/my-script.sh | bash

它不起作用,因为我的脚本中包含read语句。由于某些原因,在进行bash传输时这些命令不起作用:

# Piping to bash works in general
$ echo 'hi'
hi
$ echo "echo 'hi'" | bash
hi

# `read` works directly
$ read -p "input: " var
input: <prompt>

# But not when piping - returns immediately
$ echo 'read -p "input: " var' | bash
$

而不是提示input:和要求一个值,而是由read传递了read命令bash

有谁知道我可以通过管道read传递脚本到bash吗?

Answers:


16

read从标准输入读取。但是bash进程的标准输入已被脚本使用。根据外壳程序的不同,要么read由于外壳程序已经读取并解析了整个脚本而要么什么都不读取,否则read将消耗脚本中不可预测的行。

简单的解决方案:

bash -c "$(wget -O - http://example.com/my-script.sh)"

更复杂的解决方案,更多是出于教育目的,而不是为了说明此特定情况而提供好的解决方案:

echo '{ exec </dev/tty; wget -O - http://example.com/my-script.sh; }' | bash

很好,谢谢。这几乎一样优雅。
罗宾·温斯洛

2

流程替换将满足您的要求:

bash <(wget ...)

就是说,我不得不在这里质疑你的动机。如果您控制Web服务器(并使用https),那么这也许很有意义。但是仅仅从互联网盲人那里运行脚本是非常危险的。


just running a script from the internet blind is very risky-是的,我们知道这很冒险,但是人们可以选择信任某些组织的脚本。请参阅有关@ Xen2050答案的评论中的讨论。
罗宾·温斯洛

1

有什么问题吗:

wget -O tmpscript.sh http://example.com/my-script.sh
chmod +x tmpscript.sh
tmpscript.sh


'cos然后我必须创建一个文件。我的意思是可以,有点混乱。
罗宾·温斯洛

1
真正。尽管这是使用的一个很好的理由/tmp,但是许多程序都使用临时文件。我非常乐意立即运行任何下载的脚本,而无需先看一下……
Xen2050 2015年

那就是你的电话。许多项目提供了这些一线工具,例如Dockerohmyzsh和我现在不记得的其他项目。在这种情况下,这是我要在自己的存储库中的新系统上运行的安装脚本。正如我写的那样,我不太担心它的内容。
罗宾·温斯洛

3
我在想其他任何人找到这个问题(也许是一个全新的用户)可能对此并不了解。
Xen2050
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.