web-dev-qa-db-ja.com

ソースコード内のread -pのプロンプトで長い文字列を複数行に分割する方法は?

/bin/shとして実行されるインストールスクリプトを書いています。

ファイルを要求する行があります:

read -p "goat may try to change directory if cd fails to do so. Would you like to add this feature? [Y|n] " REPLY

この長い行を多くの行に分割して、80文字を超えないようにしたいと思います。スクリプトのソースコード内の行について話しています。 notスクリプトの実行時に画面に実際に印刷される行について!

私が試したこと:

  • フリストアプローチ:

    read -p "oat may try to change directory if cd fails to do so. " \
        "Would you like to add this feature? [Y|n] " REPLY
    

    これはWould you like to add this feature? [Y|n]を印刷しないため機能しません。

  • 2番目のアプローチ:

    echo "oat may try to change directory if cd fails to do so. " \
        "Would you like to add this feature? [Y|n] "
    read REPLY
    

    同様に機能しません。プロンプトの後に改行を出力します。 -nオプションをechoに追加しても効果はありません。出力するだけです。

    -n goat oat may try to change directory if cd fails to do so. Would you like to add this feature? [Y|n]
    # empty line here
    
  • 私の現在の回避策は

    printf '%s %s ' \
        "oat may try to change directory if cd fails to do so." \
        "Would you like to add this feature? [Y|n] "
    read REPLY
    

そしてもっと良い方法があるかしら。

/bin/sh互換のソリューションを探していることを思い出してください。

21

まず、変数を使用して、テキスト行から読み取りを切り離します。

text="line-1 line-2"             ### Just an example.
read -p "$text" REPLY

このようにして、問題は次のようになります。変数に2行を割り当てる方法。

もちろん、これを行う最初の試みは次のとおりです。

a="line-1 \
line-2"

そのように書かれて、var aは実際に値line-1 line-2を取得します。

しかし、これによって作成されるインデントの欠如が気に入らない場合は、ヒアドキュメントから行にvarを読み込もうとすることがあります(ヒアドキュメント内のインデントされた行にはスペースではなくタブが必要です。正しく動作するため):

    a="$(cat <<-_set_a_variable_
        line-1
        line-2
        _set_a_variable_
    )"
echo "test1 <$a>"

しかし、実際には2行が$aに書き込まれるため、失敗します。 1行だけを取得するための回避策は次のとおりです。

    a="$( echo $(cat <<-_set_a_variable_
        line 1
        line 2
        _set_a_variable_
        ) )"
echo "test2 <$a>"

それは近いですが、他の追加の問題を作成します。

正しい解決策。

上記のすべての試みは、この問題を必要以上に複雑にするだけです。

非常に基本的でシンプルなアプローチは次のとおりです。

a="line-1"
a="$a line-2"
read -p "$a" REPLY

特定の例のコードは次のとおりです(read-pをサポートするシェルの場合):

#!/bin/dash
    a="goat can try change directory if cd fails to do so."
    a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
        read -p "$a" REPLY

他のすべてのシェルには、次を使用します。

#!/bin/dash
    a="goat can try change directory if cd fails to do so."
    a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
        printf '%s' "$a"; read REPLY
18
user79743

私は @ BinaryZebraのアプローチ を使用して変数をよりクリーンにしていますが、あなたが試みていた方法でそれを行うこともできます。引用符の中に改行を入れるだけです:

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY
1
terdon

行末のバックスラッシュは、出力の実際の改行ではなく、複数行にわたるコマンドの継続を可能にします。

たとえば、最初のアプローチはコマンドになります

read -p "goat can try change directory if cd fails to do so. " "Would you like to add this feature? [Y|n] " REPLY

複数行を読み取って出力する理由がわかりませんが、プロンプト行にはreadを使用し、前の行にはechoを使用します。

複数行にわたってコードを読みやすくするには、行間で引用符を閉じたり開いたりしないでください。

これを試して:

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY
1
Ian Petts

これだけはどうですか:

#!/ bin/bash 
 read -p "Hello 
 world 
これは
複数行
プロンプトです: "プロンプト
エコー$プロンプト
0
Desmond