Wie kann man einen langen String in der Eingabeaufforderung read -p im Quellcode in mehrere Zeilen aufteilen?

18

Ich schreibe ein Installationsskript, das als ausgeführt wird /bin/sh.

Eine Zeile fordert zur Eingabe einer Datei auf:

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

Ich möchte diese lange Zeile in viele Zeilen aufteilen, damit keine mehr als 80 Zeichen enthält. Ich spreche über die Zeilen im Quellcode des Skripts; nicht über die Zeilen, die beim Ausführen des Skripts tatsächlich auf dem Bildschirm gedruckt werden sollen!

Was ich versucht habe:

  • Frist Ansatz:

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

    Dies funktioniert nicht, da nicht gedruckt wird Would you like to add this feature? [Y|n].

  • Zweiter Ansatz:

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

    Funktioniert nicht so gut. Nach der Eingabeaufforderung wird eine neue Zeile gedruckt. Das Hinzufügen einer -nOption echohilft nicht: Es wird nur gedruckt:

    -n goat can try change directory if cd fails to do so. Would you like to add this feature? [Y|n]
    # empty line here
  • Meine aktuelle Problemumgehung ist

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

und ich frage mich, ob es einen besseren Weg gibt.

Denken Sie daran, dass ich nach einer /bin/shkompatiblen Lösung suche .

Mateusz Piotrowski
quelle
1
Ich schlage vor, dass Sie 1. ein breiteres Terminal- und / oder Editorfenster verwenden (z. B. ein Terminal mit 192 Spalten und 51 Zeilen auf meinem 1440p-Monitor - ideal zum Nachverfolgen von Protokolldateien und Bearbeiten von Quellcode in vim) und 2. lernen, das zu akzeptieren Die Tatsache, dass Quellcode-Zeilen manchmal länger als 80 Zeichen sind, ist unvermeidlich. Wenn ich eine kleinere Schriftart verwenden würde, könnte ich ein noch breiteres Terminal verwenden, aber meine aktuelle Konfiguration ist ein guter Kompromiss zwischen Breite und Lesbarkeit.
cas

Antworten:

16

Koppeln wir zunächst den Lesevorgang mit einer Variablen von der Textzeile ab:

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

Auf diese Weise ergibt sich das Problem: So weisen Sie einer Variablen zwei Zeilen zu.

Ein erster Versuch dazu ist natürlich:

a="line-1 \
line-2"

So geschrieben, aerhält die Variable tatsächlich den Wert line-1 line-2.

Aber Sie mögen nicht den Mangel an Einrückungen, den dies erzeugt, na ja, dann können wir versuchen, die Zeilen von einem Here-Doc in den Var einzulesen (beachten Sie, dass die eingerückten Zeilen innerhalb des Here-Doc einen Tabulator benötigen, keine Leerzeichen, richtig arbeiten):

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

Das würde aber scheitern, da eigentlich zwei Zeilen geschrieben werden $a. Eine Problemumgehung, um nur eine Zeile abzurufen, könnte sein:

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

Das ist naheliegend, wirft aber noch weitere Probleme auf.

Richtige Lösung.

Alle oben genannten Versuche machen dieses Problem nur komplexer, als es sein muss.

Ein sehr grundlegender und einfacher Ansatz ist:

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

Der Code für Ihr spezielles Beispiel lautet (für jede Shell, deren readUnterstützung -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

Für alle anderen Shells verwenden Sie:

#!/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

quelle
@ BinaryZebra Ich weiß. Ich habe gerade das "für jede Shell" korrigiert, da nicht alle Shells gelesen haben und nicht alle, die -p haben.
Terdon
@terdon Wir sind uns einig Das ist der Grund für den Dank :-). Danke noch einmal.
1

Der Backslash am Ende der Zeilen ermöglicht die Fortsetzung des Befehls über mehrere Zeilen, nicht über tatsächliche Zeilenumbrüche in der Ausgabe.

So wird beispielsweise Ihr erster Ansatz zum Befehl

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

Ich bin nicht sicher, warum Sie lesen möchten, um mehrere Zeilen auszugeben, aber ich würde einfach readfür die Eingabeaufforderungszeile und echodie vorhergehenden Zeilen verwenden.

Um den Code über mehrere Zeilen lesbarer zu machen, schließen / öffnen Sie Ihre Anführungszeichen nicht zwischen den Zeilen.

Versuche dies:

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY
Ian Petts
quelle
Ich möchte nicht, dass es zwei Zeilen druckt! Ich möchte nur den Code in 80 Zeichen pro Zeile im Quellcode des Skripts passen ! Vielen Dank für die Antwort :)
Mateusz Piotrowski
Ich mag den von Ihnen vorgeschlagenen Ansatz nicht, weil es keine Einrückung gibt. Wenn my readinnerhalb einer Funktion eingerückt ist, scheint Ihr Ansatz die Lesbarkeit zu beeinträchtigen.
Mateusz Piotrowski
1

Ich finde, @ BinaryZebras Ansatz , eine Variable zu verwenden, ist sauberer, aber Sie können es auch so machen, wie Sie es versucht haben. Sie müssen nur die Zeilenumbrüche in den Anführungszeichen belassen:

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY
terdon
quelle
Glauben Sie, dass das Hinzufügen von Zeilenumbrüchen nach jeder Zeile die Lesbarkeit verbessern würde? Weil ich nicht nach einer Möglichkeit gesucht habe, \nmich in meine Eingabeaufforderung einzufügen . Ich wollte den Code nur in mehrere Zeilen aufteilen, damit jede Zeile höchstens 80 Zeichen lang ist.
Mateusz Piotrowski
1
@MateuszPiotrowski oh, das macht viel mehr Sinn. Dann ist meine Antwort nicht sehr nützlich. Bitte bearbeiten Sie Ihre Frage und stellen Sie klar, dass Sie den Code und nicht die Ausgabe teilen möchten. Ich bin jetzt auf dem Handy, aber ich werde sehen, ob ich mir morgen etwas einfallen lassen kann.
Terdon
1
@MateuszPiotrowski erledigt, ich habe eine funktionierende Version von dem hinzugefügt, was du ursprünglich versucht hast.
Terdon
0

Was ist nur damit:

#! / bin / bash
read -p "Hallo
Welt
das ist ein
mehrzeilig
Eingabeaufforderung: "PROMPT
echo $ PROMPT

Desmond
quelle
Wie rücken Sie es ein?
Mateusz Piotrowski