2016-07-28 6 views
1

Ich automatisiere eine FTP-Sitzung, aber ich möchte stdout und Pipe es in die Datei. Ich habe mit 3 Optionen kommen:Wohin pipe ich bei Verwendung einer Inline-Datei? << EOF ... EOF?

Option 1

ftp -i ftpServer >stdoutFile <<EOF 
cd somewhere 
get something 
EOF 

Option 2

ftp -i ftpServer <<EOF >stdoutFile 
cd somewhere 
get something 
EOF 

Option 3

ftp -i ftpServer <<EOF 
cd somewhere 
get something 
EOF > stdoutFile 

Ich habe anscheinend Syntaxfehler mit allen von ihnen, und keiner von ihnen scheint zu funktionieren.

Ich habe das Gefühl, dass ich das irgendwie schon früher habe, aber ich kann mich nicht erinnern, wie.

bearbeiten

Die Syntaxfehler sind immer noch vorhanden. Es scheint, als ob ich, wenn ich diese Methode mit einem Here-Dokument namens EOF benutze, diesen Delimeter nirgendwo anders im Skript benutzen kann - komisch.

Der genaue Fehler, der erzeugt wird, ist tatsächlich ein Fehler bei der nächsten if-Anweisung Terminierung. Zum Beispiel:

if [ condition ] 
then 
    ftp -i ftpServer >stdoutFile <<EOF 
    cd somewhere 
    get something 
    EOF 
fi 

if [ something else ] 
then 
    somethingWithaHereDoc <<EOF 
    foo 
    bar 
    EOF 
fi 

ich Syntax error near unexpected token 'fi' zeigt auf die Zeile des letzten fi.

Die FTP-Verbindung hängt jetzt. Ich benutze eine ~/.bashrc Datei und es funktioniert in einer anderen Konsole, aber nicht im Skript. Ich hatte versehentlich eine Named Pipe in dem Verzeichnis, wodurch die FTP-Sitzung hängen blieb. Alles ist jetzt gelöst. Vielen Dank!

Der Grund, warum ich das tue, ist, weil ich eine bestimmte Datei von einem FTP-Server herunterladen möchte. Ich liste den Inhalt des Verzeichnisses auf, verlasse die FTP-Sitzung und verarbeite sie in bash und starte dann eine weitere FTP-Sitzung, um die Datei zu erhalten, die ich gewählt habe.

+2

Optionen 1 und 2 sollten beide arbeiten. –

+2

Bitte zeigen Sie die Syntaxfehler, die Sie erhalten, und den Kontext. Option 3 wird sicherlich fehlschlagen, aber die ersten beiden sollten in Ordnung sein. – cdarke

+0

Ihre erste und zweite Option oben sind korrekt, aber Ihr 'EOF' muss das einzige Ding auf der Linie sein: keine führenden Tabulatoren oder Leerzeichen, auch kein hinterherliegender Trödel. Das Problem, das Sie sehen, ist, dass bash den Terminator nicht erkennt. – gilez

Antwort

4

Die <<EOF nur Signale, dass ein hier Dokument auf der nächsten Zeile beginnen. Sie können dies frei mit anderen Weiterleitungen mischen, so dass die Optionen 1 und 2 beide gültig sind. Es gibt keinen Unterschied zwischen den beiden, obwohl ich vermute, dass die meisten Leute Option 1 vorziehen und vorschlagen würden, da sie die Ausgabeumleitung nicht in das hier vorliegende Dokument "einbricht".

Wenn Sie Syntaxfehler entweder mit Option 1 oder Option 2 bekommen, sind sie fast sicher nicht mit dem hier Dokument selbst verwandt.

Option 3 ist ungültig, da das Trennzeichen für das Dokument hier in einer Zeile selbst vorkommen muss, und weil es nicht Teil des ursprünglichen Befehls ist.

+0

Das hilft meinem Verständnis, danke. Ich habe die Frage bearbeitet, weil ich immer noch Probleme habe. –

+0

Bitte fügen Sie einen * exact * -Befehl hinzu, der zusammen mit dem * exact * -Fehler einen Fehler erzeugt. Was Sie jetzt haben, ist nicht genug, um das Problem zu diagnostizieren. Sie sollten das Trennzeichen an anderer Stelle im vorliegenden Dokument verwenden können. nur das Trennzeichen selbst in einer einzelnen Zeile sollte das hier Dokument beenden. – chepner

0

Sie möchten wahrscheinlich die erste EOF zitieren. Option 3 wird das Heredoc nicht beenden, also ist es falsch, aber die anderen 2 sollten funktionieren (ich verwende generell Option 2). Möchten Sie ssh anstelle von ftp (dh, versuchen Sie, eine Operation, die Ausgabe erzeugt oder eine Datei zu greifen) vorzuforschen?unten ist, wie ich ssh:

ssh ... << 'EOF' > file 
remote commands here 
EOF 

kann auch über die Pipeline zu einem lokalen Prozess:

ssh ... << 'EOF' | awk ... 
remote commands here 
EOF 
+2

Es ist nichts in der Frage zu suggerieren, dass die Angabe "EOF" entweder notwendig oder falsch ist; Es kommt nur darauf an, was der Inhalt des vorliegenden Dokuments sein soll. – chepner

+0

Ihr Recht, Zitat ist nicht immer erforderlich, außer dass in diesem Fall der Inhalt des heredoc explizit eine CD enthält, die wahrscheinlich nicht auf dem lokalen Server, sondern auf dem Remote-Server gewünscht wird. Um es auf dem Remote-Server auszuführen, müssen Sie es – CSTobey

+2

@ CSTobey, falsch angeben. Die Anführungszeichen verhindern, dass ** Erweiterungen ** lokal ausgeführt werden, aber die 'cd' befindet sich nicht in irgendeiner Art von Substitution oder Erweiterung. Wenn es zB '$ (irgendwo cd; printf '% q \ n' * .txt)' 'wäre, nicht nur' cd somewhere', dann hätten Sie recht, aber das ist nicht der Fall. –