パイプからユーザー入力を読み取る方法は?


9

confirmation.sh次の内容の名前のファイルがあるとします。

#!/bin/bash
echo -n "Are you sure [Y/n]? "
read line
case "$line" in
    n|N) echo "smth"
        ;;
    y|Y) echo "smth"
        ;;
esac

このスクリプトを次のように実行したいと思います。

cat confirmation.sh | sh

私が見るAre you sure [Y/n]?と、スクリプトが中断されました。どうしたの?


2
あなたは/bin/bash強打の行にいますが、.sh拡張機能を使用してスクリプトをにパイプしようとしshます。あなたが持っているコードは両方と互換性があるので問題ではありませんが、指摘する価値があります。
Graeme

回答:


8

他の人が言ったようので、これがあるstdinshが通常であるようにパイプから読み取るようにリダイレクトされている、それが端末に接続されていません。これを回避するために実行できることの1つは、を使用/dev/ttyしてスクリプトを強制的にターミナルから読み取らせることです。例えば:

#!/bin/sh

read -p "Are you sure [Y/n]?" line </dev/tty
case "$line" in
  y|Y) echo "confirmed"
    ;;
  *) echo "not confirmed"
    ;;
esac

通常、ユーザーが入力をスクリプトで実行できないようにしたい場合にのみ、これを実行します。例:

echo Y | sh confirmation.sh

これは、ユーザーがYプロンプトで自動的に入力することを期待している場合でも、端末から読み取られます。これを行うにはパスワードが必要なプログラムでは一般的です。


2
sh 3<<CONFIRM /dev/fd/3
    $(cat ./confirmation.sh)
CONFIRM

sh 3<./confirmation.sh /dev/fd/3

注:上記の2つの例で私を訂正してくれた@Graemeに感謝します...

stdin明確にしておくと、はるかに簡単です。

2<./confirmation.sh . /dev/stderr

または、端末の0 1 2はすべて同じファイルなので、次のように追加します。

read line <&2

そしてあなたの

cat ./confirmation.sh | sh

うまく動作します。


私はこれらのどれも、前のものとは別に機能させることができません。
Graeme

奇妙なことに、彼らはすべて私のために働いた...私は何かの真ん中にいますが、... 10分ほどでもう一度テストできます。それまでの間、大胆なコメントをお願いします。誤報を流したくない。
mikeserv 2014年

@Graeme-初めて見逃した理由がわからない-同時にすべてをテストしたと誓ったかもしれない-しかし、最初の2つは正しく動作するように変更が必要です。ありがとうございました。
mikeserv 2014年

よさそうだ、私はそれからソースするとき、それはまだターミナルから読みませんstderr。私はおそらくそうすべきですが、理由はわかりません。
Graeme 2014年

@Graeme-奇妙な-私はそれをダッシュ​​sh zshとbashで試した。すべてが働いた。
mikeserv 2014年

0

これは、スクリプトにパイプ処理されている単一の引数に対して機能しました。

if [ -p /dev/stdin ]; then set -- "$( cat )"; fi

その後$1、他のスクリプトの動作と互換性のある位置引数()でパイプ処理されたデータにアクセスできます。


からinfo test

[ -p /dev/stdin ]-p FILEFILEが存在し、名前付きパイプである場合、Trueです。


-1

簡単に言えば、それはできません。パイプはstdoutをstdinにリダイレクトするため、最初のコマンドからの出力をパイプステートメントの2番目のコマンドへの入力として既にリダイレクトしているため、インタラクティブスクリプトを実行できません。

あなたはこのようなことをしたいと思っているかもしれません:

cat confirmation.sh > ask.sh && sh ask.sh

あなたはまだ対話型スクリプトを実行できます、私の答えを見てください。また、なぜだけではないのsh confirmation.shですか?
Graeme
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.