使用cat和pipe的Bash读取命令



我有两个脚本:

install.sh

#!/usr/bin/env bash
./internal_install.sh

internal_install.sh

#!/usr/bin/env bash
set -x
while true; do
read -p "Hello, what's your name? " name
echo $name
done

当我运行./install.sh时,所有工作如预期:

> ./install.sh 
+ true
+ read -p 'Hello, what'''s your name? ' name
Hello, what's your name? Martin
+ echo Martin
Martin
...

但是,当我运行cat ./install.sh | bash时,read函数不会阻塞:

cat ./install.sh | bash
+ true
+ read -p 'Hello, what'''s your name? ' name
+ echo
+ true
+ read -p 'Hello, what'''s your name? ' name
+ echo
...

这只是使用curl的简化版本,导致同样的问题:

curl -sl https://www.conteso.com/install.sh | bash

我如何使用curl/cat在内部脚本中阻止read?

read默认从标准输入读取。当您使用管道时,标准输入是管道,而不是终端。

如果您希望始终从终端读取,请将read输入重定向到/dev/tty

#!/usr/bin/env bash
set -x
while true; do
read -p "Hello, what's your name? " name </dev/tty
echo $name
done

但是您可以通过将脚本作为参数提供给bash而不是管道来解决这个问题。

bash ./install.sh

当使用curl获取脚本时,您可以使用进程替换:

bash <(curl -sl https://www.conteso.com/install.sh)

最新更新