Übergeben einer Variablen an ein Bash-Skript, das 'EOF' verwendet und die Variable als Literal betrachtet [geschlossen]

9

In diesem Skript wird "$ 1" in der / test-Datei gespeichert.

#!/bin/bash
cat > /test << 'EOF'
$1
EOF

Die Wahrheit ist ... ich muss behalten

'EOF'

als 'EOF', weil mein Argument ($ 1) Dollarzeichen enthält.

Aber ich brauche dieses Argument, um gespeichert zu werden, anstatt $ 1

user72685
quelle
1
"Weil mein Argument ( $1) Dollarzeichen enthält." Nicht, wenn es sich auf den ersten Befehlszeilenparameter bezieht. Dies wurde ersetzt, bevor Ihr Skript ausgeführt wurde. Sie müssen es in der Befehlszeile entkommen.
Goldlöckchen
Sie haben mehrere verwandte Fragen zu dieser Aufgabe gestellt, und das Fortschreiten der Fragen zeigt, dass Sie nicht wirklich verstehen, was vor sich geht, und wahrscheinlich nicht den einfachsten Ansatz wählen. Es ist schwierig, Ihnen zu helfen, ohne zu wissen, was Sie tun möchten. Ich empfehle daher, dass Sie eine Frage stellen, in der Sie Ihre Gesamtaufgabe klar erläutern und die Antworten nicht auf die Verwendung eines bestimmten Tools beschränken. Sagen Sie beispielsweise nicht "Ich möchte catDollarzeichen verwenden und behalten", sondern "Ich möchte das ändern httpd.conf, um <einige Einstellungen> auf <diese Weise> zu ändern".
Gilles 'SO - hör auf böse zu sein'
@ Gilles, letztendlich habe ich beschlossen, über Python in eine andere Datei zu schreiben und dann ein Bash-Skript zu verwenden, um diese Datei in die Originaldatei zu schreiben, die bearbeitet wurde. Dieser Prozess ist viel einfacher. cat / temp_file> $ 1
user72685
@ Gilles, der Grund, warum meine Fragen keinen Sinn ergeben, liegt darin, wie Bash-Skripte mit Variablen umgehen, die an sie weitergegeben werden. Es gibt zu viele Dinge, die entkommen müssen, und dennoch gibt es keine Funktion, die im laufenden Betrieb codiert und decodiert werden kann.
user72685
@ Gilles, das einzige, was für mich ein bisschen Sinn machte, war base64, aber warum muss man ihre Sachen verschlüsseln müssen, um zu einem Bash-Skript überzugehen. die ganzen drei vorwärts Schrägstriche, um einem Backtick zu entkommen und etc .. es scheint mir wie eine Code-Hölle
user72685

Antworten:

15

Wenn Sie Ihre vorherige Frage weiterverfolgen, möchten Sie, dass sowohl nicht interpretierter als auch interpretierter Text in eine Datei aufgenommen wird. Verwenden Sie in diesem Fall zwei verschiedene cats (oder echos):

cat > /test <<'EOF'
some uninterpreted text $(pwd)
not substituted: $1
EOF
cat >> /test <<EOF
but this will substitute: $1
EOF

Hier ist einiges los: Erstens die Heredoc- Syntax mit <<. Wenn Sie Anführungszeichen in diese Abschlusszeichenfolge einfügen, wie im ersten oben, wird der gesamte Heredoc nicht interpretiert - keine Parameter und keine Ersetzungen. Wenn Sie nicht keine Anführungszeichen verwenden, wie in der zweiten cat oben, Variablen wie $1durch ihre Werte und Befehlsersetzungen ersetzt werden in den Text aufgenommen werden. Sie können wählen, ob Sie die Zeichenfolge "EOF" in Anführungszeichen setzen möchten oder nicht, je nachdem, ob Sie Ersetzungen wünschen oder nicht.

Um beide cats in dieselbe Datei zu setzen, verwenden wir die >> Umleitung für die zweite (und spätere) Umleitung: Das bedeutet, dass an die Datei angehängt wird. Für den ersten verwenden wir eine einzelne >, um die Datei zu löschen und neu zu beginnen.

Beachten Sie, dass selbst wenn Variablen ersetzt werden , zusätzliche Dollarzeichen im Wert dieser Variablen nicht selbst ersetzt werden:

foo='$bar'
bar=hello
cat <<EOF
$foo
EOF

wird ausgegeben:

$bar

ohne den $barWert von in zu ersetzen .

Wenn Sie jedoch ein "$" im Argument für dieses gesamte Skript angeben, müssen Sie es in der Befehlszeile maskieren oder das Ganze in einfache Anführungszeichen setzen. Alternativ können Sie durch Ersetzen von Befehlen wie in Ihrer anderen Frage den Inhalt einer gesamten Datei direkt einfügen, einschließlich aller Dollarzeichen im Dateiinhalt. Stellen Sie sicher, dass Sie dort die Ersetzungszeichenfolge angeben:

oo.sh "$(cat myfile)"

wird den Körper von myfileas bekommen $1und kann dann catoder echoes nach Bedarf. Es gelten die gleichen Einschränkungen wie in meiner Antwort : Es gibt eine Begrenzung für die Länge der Befehlszeilenargumente. Wenn Ihre Datei länger wird, sollten Sie einen anderen Ansatz finden. Sie können herausfinden, mit welchem ​​Limit Ihr System begrenzt istgetconf ARG_MAX

Michael Homer
quelle
1

Klingt so, als ob Sie einfach die eine Variable in die Datei ausgeben möchten. In diesem Fall funktioniert dies:

echo $1 >/test

Beachten Sie, dass /testsich das Verzeichnis im Stammverzeichnis befindet, für das normale Benutzer normalerweise keine Schreibberechtigung haben.

BEARBEITEN: Beachten Sie, dass Sie die Dollarzeichen enthaltende Zeichenfolge in der Befehlszeile angeben müssen . Hier erfolgt die Ersetzung, und das Skript kann nachträglich nichts dagegen tun.

Tom Zych
quelle
Ich denke, Sie haben jetzt die richtige Antwort. +1
Goldlöckchen
@ MichaelHomers Antwort ist viel vollständiger und enthält nützliche Informationen zu diesen Dokumenten, die ich vergessen hatte. Seine Antwort sollte akzeptiert werden (es sei denn, jemand anderes veröffentlicht natürlich eine noch bessere).
Tom Zych