... | ... | @@ -9,13 +9,13 @@ Auf dieser Seite finden Sie die Anleitungen zur Benutzung der Software für die |
|
|
|
|
|
Hinweise zur Nutzung des VPNs \[https://its.h-da.io/infra-docs/docs/vpn.html von außerhalb der Hochschule oder des FBI-Netzes\]
|
|
|
|
|
|
== Generelles ==
|
|
|
# Generelles
|
|
|
|
|
|
* Die Maschinen sind nur aus dem \[https://its.h-da.io/infra-docs/docs/vpn.html VPN\] und dem Hochschulnetz vor Ort erreichbar
|
|
|
* Die Maschinen sind nur aus dem [VPN](https://its.h-da.io/infra-docs/docs/vpn.html) und dem Hochschulnetz vor Ort erreichbar
|
|
|
* Die Anmeldung an den Maschinen erfolgt per SSH (nur aus dem VPN) mit Ihrem hda-Benutzer auf dem Master-Node: `master.bdt.users.h-da.cloud`. Dies ist der Master-Node für Couchbase, MongoDB und Hadoop
|
|
|
* Eine detaillierte Anleitung zu SSH & Co. dazu finden Sie auf der Seite [[Big Data Cluster|Big%20Data%20Cluster]]
|
|
|
|
|
|
== Überblick ==
|
|
|
## Überblick
|
|
|
|
|
|
```
|
|
|
xxxxxxxx
|
... | ... | @@ -42,7 +42,7 @@ Hinweise zur Nutzung des VPNs \[https://its.h-da.io/infra-docs/docs/vpn.html von |
|
|
xxxxxxxxxxxxxxxxx
|
|
|
```
|
|
|
|
|
|
== MongoDB ==
|
|
|
## MongoDB
|
|
|
|
|
|
MongoDB ist als Cluster über 7 Nodes konfiguriert. Der Master-Node lautet: `master.bdt.users.h-da.cloud`. Dieser ist nur per SSH aus dem VPN, sowie vor Ort aus dem Hochschulnetz, erreichbar.
|
|
|
|
... | ... | @@ -50,48 +50,45 @@ MongoDB ist als Cluster über 7 Nodes konfiguriert. Der Master-Node lautet: `mas |
|
|
|
|
|
Wird dort `true` zurückgegeben, sind Sie zum richtigen Master verbunden und können dort Lese-/Schreiboperationen durchführen.
|
|
|
|
|
|
=== Version ===
|
|
|
### Version
|
|
|
|
|
|
5.0.6
|
|
|
|
|
|
=== Kurzanleitung ===
|
|
|
### Kurzanleitung
|
|
|
|
|
|
* Sie erhalten für die Arbeit mit MongoDB einen eigenen User: z.B. einen `GruppeNN`-Benutzer. Gruppennummer und Passwort erhalten Sie im 1. Praktikum.
|
|
|
* Mit diesem können Sie auf einer bereits angelegten Datenbank arbeiten, welche ebenfalls `GruppeNN` heisst, d.h. `Datenbankname` = `GruppeNN`
|
|
|
* Mit diesem können Sie auf einer bereits angelegten Datenbank arbeiten, welche ebenfalls `GruppeNN` heisst, d.h. `Datenbankname` = `GruppeNN`
|
|
|
* Die Shell für MongoDB wird mit `mongosh --host master.bdt.users.h-da.cloud -u GruppeNN -p ''Passwort'' GruppeNN` gestartet und mit `exit` oder STRG+D wieder verlassen. Das Passwort erhalten Sie im 1. Praktikum vom Dozenten.
|
|
|
|
|
|
<!--* Hinweis: Wenn Sie den <code>primary</code> nicht kennen, können Sie sich auch mit <code>mongosh --host master.bdt.users.h-da.cloud -u GruppeNN -p ''Passwort'' GruppeNN</code> zu einem beliebigen Node des Clusters verbinden und den <code>primary</code> mit <code>db.isMaster().primary</code> in der MongoDB-Shell abfragen. Verbinden Sie sich dann mit einer neuen MongoSH zu der angezeigten Adresse.-->
|
|
|
|
|
|
* Zum Einfügen einzelner Datensätze können Sie das [save-Kommando](https://docs.mongodb.com/manual/reference/method/db.collection.save/) verwenden.
|
|
|
* Für Massendaten eignet sich [mongoimport](https://docs.mongodb.com/manual/reference/program/mongoimport/index.html).
|
|
|
* Für Massendaten eignet sich [mongoimport](https://docs.mongodb.com/manual/reference/program/mongoimport/index.html).
|
|
|
|
|
|
**Beispiel:** `mongoimport -d=GruppeNN -c= -u=GruppeNN -p= --file --authenticationDatabase GruppeNN --type --host=master.bdt.users.h-da.cloud -v`
|
|
|
* Ein einfaches Graphisches User Interface für MongoDB bietet beispielsweise das Tool [Studio 3T](https://robomongo.org/download) (früher Robo 3T, ehem. Robomongo).
|
|
|
|
|
|
=== MongoDB Compass ===
|
|
|
### MongoDB-Compass
|
|
|
|
|
|
\[MongoDB Compass\](https://www.mongodb.com/download-center/compass) ist ein graphisches Werkzeug für MongoDB Datenbanken, das unter Windows, Linux, und Mac OS frei zum Download zur Verfügung steht.
|
|
|
[MongoDB Compass](https://www.mongodb.com/download-center/compass) ist ein graphisches Werkzeug für MongoDB Datenbanken, das unter Windows, Linux, und Mac OS frei zum Download zur Verfügung steht.
|
|
|
|
|
|
Nach der Installation kann ein neues Verbindungsdokument zum Master (`master.bdt.users.h-da.cloud`) aus dem MongoDB-Verbund angelegt werden. Geben Sie dazu die nötigen Anmeldeinformationen bei _Advanced Connection Options_ an:
|
|
|
|
|
|
Tab General
|
|
|
#### Tab General
|
|
|
|
|
|
* **Connection String Schema:** mongodb
|
|
|
* **Host:** master.bdt.users.h-da.cloud:27017
|
|
|
* **Direct Connection:** Häkchen setzen
|
|
|
|
|
|
Tab Authentication
|
|
|
#### Tab Authentication
|
|
|
|
|
|
* **Username:** GruppeNN
|
|
|
* **Passwort:** Praktikum
|
|
|
* **Authentication Database:** GruppeNN
|
|
|
* **Authentication Mechanism:** Default
|
|
|
|
|
|
Tab TLS/SSL
|
|
|
#### Tab TLS/SSL
|
|
|
|
|
|
* **SSL/TLS Connection:** Off
|
|
|
|
|
|
Alle anderen Tabs und Eingabefelder ignorieren. Der Connection-String sieht dann wie folgt aus: \`\`
|
|
|
Alle anderen Tabs und Eingabefelder ignorieren. Der Connection-String sieht dann wie folgt aus:
|
|
|
|
|
|
```shell
|
|
|
mongodb://GruppeNN:Praktikum@master.bdt.users.h-da.cloud:27017/?tls=false&directConnection=true&authMechanism=DEFAULT&authSource=GruppeNN
|
... | ... | @@ -99,135 +96,118 @@ mongodb://GruppeNN:Praktikum@master.bdt.users.h-da.cloud:27017/?tls=false&direct |
|
|
|
|
|
Mit Klick auf **Save & Connect** wird eine Verbindung zur Datenbank aufgebaut.
|
|
|
|
|
|
=== Links ===
|
|
|
### Links
|
|
|
|
|
|
* https://docs.mongodb.com/manual/introduction/
|
|
|
* https://docs.mongodb.com/manual/crud/
|
|
|
* https://www.mongodb.com/download-center/compass
|
|
|
|
|
|
== Couchbase ==
|
|
|
## Couchbase
|
|
|
|
|
|
Couchbase ist als Cluster über 8 Nodes konfiguriert.
|
|
|
|
|
|
=== Version === 7.2.0 (Enterprise Edition)
|
|
|
### Version
|
|
|
|
|
|
=== Kurzanleitung ===
|
|
|
7.2.0 (Enterprise Edition)
|
|
|
|
|
|
### Kurzanleitung
|
|
|
|
|
|
* Sie erhalten für die Arbeit mit Couchbase einen eigenen Benutzer (`GruppeNN`) mit dazugehörigem Passwort im 1. Praktikum.
|
|
|
* Mit diesem können Sie auf einem bereits angelegten Bucket arbeiten, der den gleichen Namen wie ihr Benutzer hat
|
|
|
* Die Shell für N1QL-Abfragen wird mit `cbq -e master.bdt.users.h-da.cloud:8091 -c=GruppeNN:passwort` gestartet und mit `\QUIT;` oder STRG+D wieder verlassen \*\* Alternativ: mit `cbq -e master.bdt.users.h-da.cloud:8091 -u GruppeNN` aufrufen und dann das Passwort eingeben
|
|
|
* Die Shell für N1QL-Abfragen wird mit `cbq -e master.bdt.users.h-da.cloud:8091 -c=GruppeNN:passwort` gestartet und mit `\QUIT;` oder STRG+D wieder verlassen
|
|
|
|
|
|
**Alternativ:** mit `cbq -e master.bdt.users.h-da.cloud:8091 -u GruppeNN` aufrufen und dann das Passwort eingeben
|
|
|
|
|
|
**Weitere Alternative:** die N1QL-Shell in der \[Couchbase Weboberfläche\](https://datahub.users.h-da.cloud/) nutzen, Menüpunkt **Query** auf der linken Seite
|
|
|
* Daten laden: Einzelne Datensätze können Sie mit dem [INSERT-Kommando](https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/insert.html) einfügen. \*\* Für Massendaten verwenden Sie den [cbimport](https://docs.couchbase.com/server/current/tools/cbimport.html)[-Befehl](https://docs.couchbase.com/server/current/tools/cbimport.html%5D-Befehl).
|
|
|
**Weitere Alternative:** die N1QL-Shell in der [Couchbase Weboberfläche](https://datahub.users.h-da.cloud/) nutzen, Menüpunkt **Query** auf der linken Seite
|
|
|
* Daten laden: Einzelne Datensätze können Sie mit dem [INSERT-Kommando](https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/insert.html) einfügen. Für Massendaten verwenden Sie den [cbimport](https://docs.couchbase.com/server/current/tools/cbimport.html)[-Befehl](https://docs.couchbase.com/server/current/tools/cbimport.html%5D-Befehl).
|
|
|
|
|
|
**Beispiel:** `cbimport json --format sample -c http://master.bdt.users.h-da.cloud -u GruppeNN -p --dataset file:// -b -v` Verbindungen zu https://datahub.users.h-da.cloud sind nur über den Browser und nicht mit Kommandozeilenwerkzeugen der NoSQL-Datenbanken möglich.
|
|
|
* Daten können ebenfalls über das [Couchbase-Webinterface](https://datahub.users.h-da.cloud/) geladen werden. Dazu in der linken Leiste auf **Documents**, **Import** (oben Mitte) klicken. Dort lassen sich das Format, die Quelldatei uvm. einstellen. Es wird auch die cbimport-Kommandozeile für diesen Import angezeigt.
|
|
|
* Das Web-Interface von Couchbase erreichen Sie über https://datahub.users.h-da.cloud
|
|
|
|
|
|
=== Links ===
|
|
|
### Links
|
|
|
|
|
|
* http://developer.couchbase.com/documentation/server/5.0/introduction/intro.html
|
|
|
* https://developer.couchbase.com/documentation/server/5.0/n1ql/n1ql-language-reference/index.html
|
|
|
* https://query-tutorial.couchbase.com/tutorial/
|
|
|
|
|
|
== Hadoop ==
|
|
|
## Hadoop
|
|
|
|
|
|
Hadoop ist als Cluster über 8 Nodes konfiguriert, muss jedoch vorher explizit gestartet werden (z.B. nach dem Wechsel der NoSQL-Datenbanksoftware, typischerweise zum 4. und 5. Praktikum)
|
|
|
|
|
|
=== Version ===
|
|
|
### Version
|
|
|
|
|
|
3.3.5
|
|
|
|
|
|
=== Kurzanleitung ===
|
|
|
### Kurzanleitung
|
|
|
|
|
|
* Sie können Hadoop direkt mit Ihrem hda\*-Benutzer verwenden. Die hadoop-Dienste sind bereits für Sie gestartet.
|
|
|
* Die Anmeldung erfolgt am Hadoop-Master: `master.bdt.users.h-da.cloud` (per SSH aus dem VPN oder vor Ort an der Hochschule)
|
|
|
* Den Status der Nodes bzw. der Hadoop-Jobs können Sie hier einsehen: https://datahub.users.h-da.cloud:9870/dfshealth.html und https://datahub.users.h-da.cloud/cluster
|
|
|
* Legen Sie im _HDFS_ bitte ein Unterverzeichnis mit Ihrem hda-Benutzer mit Hilfe des Befehls `hdfs dfs -mkdir /user/hda-Benutzer` an und verwenden dieses. Anmerkung: `hadoop fs` und `hdfs dfs` sind bei der Verwendung von HDFS synonym.
|
|
|
* Legen Sie im _HDFS_ bitte ein Unterverzeichnis mit Ihrem hda-Benutzer mit Hilfe des Befehls `hdfs dfs -mkdir /user/hda-Benutzer` an und verwenden dieses.
|
|
|
|
|
|
**Anmerkung:** `hadoop fs` und `hdfs dfs` sind bei der Verwendung von HDFS synonym.
|
|
|
* Beachten Sie, dass bei der Ausführung eines hadoop-Jobs das angegebene `output`-Verzeichnis noch nicht existieren darf bzw. vorher mit `hdfs dfs -rmdir /user/hda-Benutzer/output` gelöscht werden muss
|
|
|
* Ein erstes Beispiel zur Arbeit mit Hadoop finden Sie hier: [[Hadoop-Beispiel]]
|
|
|
|
|
|
=== Links ===
|
|
|
### Links
|
|
|
|
|
|
* https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/FileSystemShell.html
|
|
|
* https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html
|
|
|
* Falls Sie das Programm lokal erstellen möchten: http://www.soulmachine.me/blog/2015/01/30/debug-hadoop-applications-with-intellij/ - Hadoop MapReduce Code auf einem lokalen PC in intelliJ ausführen und debuggen
|
|
|
|
|
|
=== Hinweise zum Praktikum / Arbeiten mit zusätzlichen Libraries ===
|
|
|
### Hinweise zum Praktikum / Arbeiten mit zusätzlichen Libraries
|
|
|
|
|
|
Anleitung zum kompletten Compilieren und Ausführen direkt auf dem Cluster:
|
|
|
Anleitung zum kompletten Kompilieren und Ausführen direkt auf dem Cluster:
|
|
|
|
|
|
==== Programm erstellen ====
|
|
|
#### Programm erstellen
|
|
|
|
|
|
* Java-Programm erstellen (z.B. `Praktikum.java`)
|
|
|
* Ggf. benötigte Libraries (z.B. json-simple-1.1.1.jar) mit scp (oder WinSCP o.ä.) in Ihr Homeverzeichnis auf `master.bdt.users.h-da.cloud` (nicht im HDFS) `/home/hda-Benutzer` kopieren. Quelle: `https://code.google.com/archive/p/json-simple/downloads`)
|
|
|
* Damit die Libraries auf allen Knoten genutzt werden können, im Programm das Toolinterface verwenden - Hinweise zur Verwendung: `https://hadoopi.wordpress.com/2013/06/05/hadoop-implementing-the-tool-interface-for-mapreduce-driver/`
|
|
|
* Ggf. benötigte Libraries (z.B. json-simple-1.1.1.jar) mit scp (oder WinSCP o.ä.) in Ihr Homeverzeichnis auf `master.bdt.users.h-da.cloud` (nicht im HDFS) `/home/hda-Benutzer` kopieren. [Quelle](https://code.google.com/archive/p/json-simple/downloads)
|
|
|
* Damit die Libraries auf allen Knoten genutzt werden können, im Programm das Toolinterface verwenden: [Hinweise zur Verwendung]( https://hadoopi.wordpress.com/2013/06/05/hadoop-implementing-the-tool-interface-for-mapreduce-driver/ )
|
|
|
|
|
|
#### Hadoop Vorbereitung
|
|
|
|
|
|
==== Hadoop Vorbereitung ====
|
|
|
Gehen Sie wie folgt vor, um hadoop Textdateien mit zufälligem Inhalt in ihrem HDFS-Benutzerverzeichnis erzeugen zu lassen:
|
|
|
|
|
|
* Gehen Sie wie folgt vor, um hadoop Textdateien mit zufälligem Inhalt in ihrem HDFS-Benutzerverzeichnis erzeugen zu lassen:
|
|
|
* `HADOOP_CLASSPATH` um verwendete Libraries erweitern: `export HADOOP_CLASSPATH=${JAVA_HOME}/lib/tools.jar:/home/hda-Benutzer/json-simple-1.1.1.jar`
|
|
|
* Wechsel ins `share`-Verzeichnis der hadoop-Installation: `cd /opt/hadoop/share/hadoop/mapreduce`
|
|
|
* Ausführen des Textdatengenerators (10 Maps/Dateien pro Node im Hadoop-Verbund) für ein 1 GB grosses Verzeichnis:
|
|
|
* Ausführen des Textdatengenerators (10 Maps/Dateien pro Node im Hadoop-Verbund) für ein 1 GB grosses Verzeichnis:
|
|
|
|
|
|
`hadoop jar hadoop-mapreduce-examples-3.3.0.jar randomwriter -Dmapreduce.randomwriter.bytespermap=13000000 /user/hda-Benutzer/random-text-data`
|
|
|
`hadoop jar hadoop-mapreduce-examples-3.3.0.jar randomwriter -Dmapreduce.randomwriter.bytespermap=13000000 /user/hda-Benutzer/random-text-data`
|
|
|
* Dokumentation zum [randomtextwriter](https://hadoop.apache.org/docs/r1.2.1/api/org/apache/hadoop/examples/RandomTextWriter.html) inkl. [Code](https://github.com/naver/hadoop/blob/master/hadoop-mapreduce-project/hadoop-mapreduce-examples/src/main/java/org/apache/hadoop/examples/RandomTextWriter.java) ist vorhanden. Der [randomwriter](https://github.com/naver/hadoop/blob/master/hadoop-mapreduce-project/hadoop-mapreduce-examples/src/main/java/org/apache/hadoop/examples/RandomWriter.java) ist ebenfalls inkl. des [Codes](https://hadoop.apache.org/docs/r1.2.1/api/org/apache/hadoop/examples/RandomWriter.html) samt Klassendokumentation verfügbar.
|
|
|
|
|
|
Hadoop kann diese Dateien bei einem erneuten Aufruf nicht überschreiben. Entweder löschen Sie diese manuell über die HDFS-Kommandos oder Sie benennen die Dateien um, z.B. mit einem eindeutigen Zeitstempel.
|
|
|
|
|
|
<!--* Input Daten ins HDFS kopieren - z.B. nach <code>/user/hda-Benutzer/input</code>
|
|
|
* Output Ordner löschen - z.B. <code>hadoop fs -rm -r -f /user/hda-Benutzer/random-text-data</code>-->
|
|
|
|
|
|
==== Compilieren ====
|
|
|
#### Kompilieren
|
|
|
|
|
|
Übersetzen und Jar erstellen: `hadoop com.sun.tools.javac.Main Praktikum.java`
|
|
|
Übersetzen des Java-Programms: `hadoop com.sun.tools.javac.Main Praktikum.java`
|
|
|
|
|
|
und die JAR-Datei erstellen: `jar cf Praktikum.jar Praktikum*.class`
|
|
|
|
|
|
==== Ausführen ====
|
|
|
#### Ausführen
|
|
|
|
|
|
Beim Ausführen die verwendeten Libraries als Parameter mit angeben:
|
|
|
Beim Ausführen die verwendeten Libraries als Parameter mit angeben:
|
|
|
|
|
|
`hadoop jar Praktikum.jar Praktikum -libjars /opt/hadoop/share/hadoop/hdfs/lib/json-simple-1.1.1.jar /user/hda-Benutzer/input /user/hda-Benutzer/output`
|
|
|
|
|
|
==== Job vorzeitig abbrechen ====
|
|
|
#### Job vorzeitig abbrechen
|
|
|
|
|
|
* Über das Kommando `yarn application -kill application_` kann ein geplanter bzw. laufender Job abgebrochen werden. Die `application_` wird beim Start des Jobs angezeigt oder in der Spalte ID im [Webinterface](https://datahub.users.h-da.cloud:8088/cluster).
|
|
|
|
|
|
==== HDFS Dateisystem im Browser ====
|
|
|
#### HDFS Dateisystem im Browser
|
|
|
|
|
|
Das HDFS lässt sich [mit einem Webbrowser](https://datahub.users.h-da.cloud:9870/explorer.html#/) aus dem VPN oder vor Ort an der Hochschule einsehen.
|
|
|
|
|
|
<!--Derzeit nicht im Praktikum verwendet, schon seit mehreren Semestern-->
|
|
|
|
|
|
<!--Pig ist ebenfalls auf allen 8 Nodes des Clusters nutzbar.
|
|
|
== Pig ==
|
|
|
Starten Sie pig auf dem Hadoop-Master-Node, d.h. auf <code>master.bdt.users.h-da.cloud</code>
|
|
|
|
|
|
=== Version ===
|
|
|
0.17.0
|
|
|
|
|
|
=== Kurzanleitung ===
|
|
|
|
|
|
* Analog zu hadoop können Sie pig direkt mit Ihrem <tt>hda-Benutzer</tt>-User verwenden.
|
|
|
* pig arbeitet ebenfalls auf dem HDFS (siehe obige Anleitung zu Hadoop).
|
|
|
* pig-Jobs werden durch die Eingabe von <code>pig <dateiname></code> gestartet.
|
|
|
* Spezifizieren Sie in Ihrem Programm mit dem <tt>STORE</tt>-Kommando den Ausgabeort im HDFS. Analog zu hadoop darf auch dieser Ausgabeordner im HDFS noch nicht existieren bzw. muss vorher gelöscht werden.
|
|
|
* Sie können mit pig auch interaktiv mit der <tt>grunt</tt>-Shell arbeiten, die sich mit <code>pig</code> starten und mit STRG+D beenden lässt.
|
|
|
* Sie finden die Tutorials von der Pig-Webseite lokal auf den Nodes unter <code>/opt/pig/tutorial</code>.
|
|
|
|
|
|
=== Links ===
|
|
|
* http://pig.apache.org/docs/r0.17.0/start.html#run-->
|
|
|
|
|
|
== PostgreSQL ==
|
|
|
## PostgreSQL
|
|
|
|
|
|
PostgreSQL wird aktuell nicht mehr auf dem Big Data Cluster, sondern als zentraler Server der Fachgruppe Datenbanken angeboten.
|
|
|
|
|
|
* Informationen zur Nutzung von PostgreSQL finden Sie hier: https://code.fbi.h-da.de/lab-docs/db/wikis/postgresql/Zentraler-PostgreSQL-Server
|
|
|
* [Informationen zur Nutzung von PostgreSQL](https://code.fbi.h-da.de/lab-docs/db/wikis/postgresql/Zentraler-PostgreSQL-Server)
|
|
|
* Melden Sie sich zunächst mit ihrem hda-Benutzer (Hochschulaccount) über SSH/PuTTY an `postgres.fbi.h-da.de` an, um eine Datenbank für sich anzulegen. Es ist nicht nötig, weiterhin angemeldet zu sein (Logout mit STRG+D), es sei denn, Sie möchten die `psql`-Shell verwenden.
|
|
|
* Die PostgreSQL-Shell starten Sie auf dem Server postgres.fbi.h-da.de mit `psql`. Diese kann mit `\q` oder STRG+D beendet werden.
|
|
|
* Zum Einfügen einzelner Datensätze verwenden Sie das insert-Kommando\[https://www.postgresql.org/docs/12.0/static/sql-insert.html\] - für Massendaten den client-seitigen \\copy-Befehl\[https://www.postgresql.org/docs/10.0/static/app-psql.html\]
|
|
|
* Zum Einfügen einzelner Datensätze verwenden Sie das [insert-Kommando](https://www.postgresql.org/docs/12.0/static/sql-insert.html) - für Massendaten den client-seitigen [\\copy-Befehl](https://www.postgresql.org/docs/10.0/static/app-psql.html%5C)
|
|
|
|
|
|
===Links===
|
|
|
### Links
|
|
|
|
|
|
* [https://www.postgresql.org/docs/17/static/index.html](https://www.postgresql.org/docs/10.0/static/index.html) |
|
|
\ No newline at end of file |