He

Here documents σε Bash

{one: "1 άσκηση", other: "%{count} ασκήσεις"}

Σχετικά με την έννοια Here documents

Στον προγραμματισμό με Bash, ένα "here document" (ή "heredoc") ανακατευθύνει πολλαπλές γραμμές εισόδου σε μια εντολή ή ένα πρόγραμμα, σαν να τις πληκτρολογούσες απευθείας στο τερματικό. Είναι ένα ισχυρό εργαλείο για να ενσωματώνεις πολυγραμμικό κείμενο μέσα στα σενάριά σου χωρίς να χρειάζεσαι εξωτερικά αρχεία ή περίπλοκους χειρισμούς συμβολοσειρών.

Βασικά χαρακτηριστικά και σύνταξη

  1. Οριοθέτης: ένα here document ξεκινά με τον τελεστή << ακολουθούμενο από μια λέξη-οριοθέτη (συχνά αποκαλούμενη "marker" ή "terminator"). Αυτός ο οριοθέτης μπορεί να είναι οποιαδήποτε λέξη διαλέξεις, αλλά συνηθίζεται να χρησιμοποιείς κάτι σαν EOF, END ή TEXT για σαφήνεια. Για πιο ευανάγνωστο κώδικα, μπορείς να χρησιμοποιήσεις κάτι περιγραφικό ως οριοθέτη, για παράδειγμα END_INSTALLATION_INSTRUCTIONS.

  2. Περιεχόμενο: μετά το αρχικό << DELIMITER, γράφεις το περιεχόμενο που θέλεις να ανακατευθύνεις. Αυτό μπορεί να είναι πολλαπλές γραμμές κειμένου, κώδικας ή οτιδήποτε άλλο.

  3. Τερματισμός: το here document τελειώνει όταν η λέξη-οριοθέτης εμφανιστεί ξανά σε μια γραμμή μόνη της, χωρίς κενά πριν ή μετά.

Βασική σύνταξη

command << DELIMITER
  Content line 1
  Content line 2
  ...
  Content line N
DELIMITER

Πώς λειτουργεί

  • Το Bash διαβάζει όλες τις γραμμές ανάμεσα στο αρχικό << DELIMITER και το τελικό DELIMITER.
  • Το Bash συνδέει αυτό το περιεχόμενο με την τυπική είσοδο της εντολής.
  • Η εντολή επεξεργάζεται αυτή την είσοδο σαν να ερχόταν από το πληκτρολόγιο.

Παράδειγμα 1: Απλή έξοδος κειμένου

cat << EOF
This is the first line.
This is the second line.
This is the third line.
EOF

Έξοδος:

This is the first line.
This is the second line.
This is the third line.

Σε αυτό το παράδειγμα:

  • Το cat είναι η εντολή.
  • Το << EOF ξεκινά το here document με οριοθέτη το EOF.
  • Οι τρεις γραμμές κειμένου είναι το περιεχόμενο.
  • Το EOF σε δική του γραμμή τερματίζει το here document.
  • Στη συνέχεια, το cat εμφανίζει το περιεχόμενο που έλαβε.

Παράδειγμα 2: Χρήση με το wc (μέτρηση λέξεων)

wc -l << END
Line 1
Line 2
Line 3
END

Έξοδος:

3

Εδώ, το wc -l μετράει τον αριθμό των γραμμών. Το here document παρέχει τις τρεις γραμμές ως είσοδο.

Παράδειγμα 3: Πέρασμα δεδομένων σε ένα σενάριο

Το σενάριο:

#!/usr/bin/env bash

# Script to process input
while IFS= read -r line; do
  echo "Processing: $line"
done

Κάλεσε το σενάριο από μια διαδραστική προτροπή bash με ένα here document:

./your_script << MY_DATA
Item 1
Item 2
Item 3
MY_DATA

Έξοδος:

Processing: Item 1
Processing: Item 2
Processing: Item 3

Παραλλαγές και προηγμένες δυνατότητες

Αυτούσιο περιεχόμενο

Το Bash εκτελεί επέκταση μεταβλητών, αντικατάσταση εντολών και αριθμητική επέκταση μέσα σε ένα here document. Υπό αυτή την έννοια, τα here documents συμπεριφέρονται σαν συμβολοσειρές μέσα σε διπλά εισαγωγικά.

cat << EOF
The value of HOME is $HOME
The current date is $(date)
Two plus two is $((2 + 2))
EOF

Έξοδος:

The value of HOME is /home/glennj
The current date is Thu Apr 24 13:47:32 EDT 2025
Two plus two is 4

Όταν ο οριοθέτης μπαίνει σε εισαγωγικά (με μονά ή διπλά εισαγωγικά), αυτές οι επεκτάσεις αποτρέπονται. Το περιεχόμενο λαμβάνεται αυτούσιο. Αυτό είναι σαν τις συμβολοσειρές μέσα σε μονά εισαγωγικά.

cat << 'EOF'
The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))
EOF

Έξοδος:

The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))

Αφαίρεση αρχικών tab

Αν χρησιμοποιήσεις το <<- (με παύλα στο τέλος) αντί για το <<, το Bash θα αφαιρέσει τυχόν αρχικούς χαρακτήρες tab από κάθε γραμμή του here document. Αυτό είναι χρήσιμο για να στοιχίζεις το περιεχόμενο του here document μέσα στο σενάριό σου χωρίς να επηρεάζεται η έξοδος.

# Note, the leading whitespace is tab characters only, not spaces!
# The ending delimiter can have leading tabs as well.
cat <<- END
	This line has 1 leading tab.
	  This line has a leading tab and some spaces.
		This line 2 leading tabs.
	END

Η έξοδος εκτυπώνεται με όλα τα αρχικά tab αφαιρεμένα:

This line has 1 leading tab.
    This line has a leading tab and some spaces.
This line 2 leading tabs.
Caution

Ο συγγραφέας δεν συνιστά αυτή τη χρήση. Ενώ μπορεί να βελτιώσει την αναγνωσιμότητα του σεναρίου,

  1. είναι εύκολο να αντικαταστήσεις κατά λάθος τους χαρακτήρες tab με κενά (ο επεξεργαστής σου μπορεί να το κάνει αυτόματα), και
  2. είναι δύσκολο να ξεχωρίσεις τη διαφορά ανάμεσα σε κενά και tab.

Πότε να χρησιμοποιείς here documents

  • Πολυγραμμική είσοδος: όταν χρειάζεται να δώσεις πολλαπλές γραμμές κειμένου σε μια εντολή.
  • Αρχεία ρυθμίσεων: ενσωμάτωση μικρών αποσπασμάτων ρυθμίσεων μέσα σε ένα σενάριο.
  • Δημιουργία κώδικα: παραγωγή κώδικα επιτόπου μέσα σε ένα σενάριο.
  • Σενάρια αλληλεπίδρασης: προσομοίωση της εισόδου του χρήστη για διαδραστικά προγράμματα.
  • Αποφυγή εξωτερικών αρχείων: όταν θέλεις να αποφύγεις τη δημιουργία προσωρινών αρχείων.

Μια τυπική χρήση μπορεί να είναι η παροχή κάποιου κειμένου βοήθειας:

#!/usr/bin/env bash

usage() {
    cat << END_USAGE
Refresh database tables.

usage: ${0##*/} [-h|--help] [-A|--no-archive]

where: --no-archive flag will _skip_ the archive jobs
END_USAGE
}

# ... parsing command line options here ...

if [[ $flag_help == "true" ]]; then
  usage
  exit 0
fi

Πιθανά μειονεκτήματα

  • Τα μεγάλα ενσωματωμένα έγγραφα μπορούν να κάνουν τον κώδικά σου πιο δυσανάγνωστο. Μπορεί να είναι καλύτερα να συνοδεύσεις το σενάριό σου με τεκμηρίωση σε ξεχωριστά αρχεία.
  • Τα here documents μπορούν να διακόψουν τη ροή του κώδικα. Μπορεί να βρίσκεσαι σε ένα βαθιά εμφωλευμένο σημείο του κώδικα όταν θέλεις να περάσεις κάποιο κείμενο σε ένα πρόγραμμα. Η στοίχιση του here document μπορεί να φαίνεται παράταιρη σε σχέση με τον κώδικα γύρω του.

Here strings

Όπως τα here documents, οι here strings (ή "herestrings") παρέχουν είσοδο σε μια εντολή. Ωστόσο, ενώ τα heredocs δίνονται ως ένα μπλοκ κειμένου, οι herestrings δίνονται ως μία μόνο συμβολοσειρά κειμένου. Τα here strings χρησιμοποιούν τη σύνταξη <<< "text".

tr 'a-z' 'A-Z' <<< "upper case this string"

Έξοδος:

UPPER CASE THIS STRING

Σε αντίθεση με τα heredocs, δεν απαιτείται οριοθέτης τερματισμού.

Γιατί να χρησιμοποιείς here strings;

Μπορείς να χρησιμοποιήσεις μια σωλήνωση αντί για ένα here string:

echo "upper case this string" | tr 'a-z' 'A-Z'

Γιατί, λοιπόν, να χρησιμοποιήσεις ένα here string;

Σκέψου την περίπτωση όπου παίρνεις τη συμβολοσειρά ως έξοδο από έναν υπολογισμό που διαρκεί πολύ, και θέλεις να τροφοδοτήσεις το αποτέλεσμα σε δύο ξεχωριστές εντολές. Χρησιμοποιώντας σωληνώσεις, πρέπει να εκτελέσεις τον υπολογισμό δύο φορές:

some_long_running_calculation | first_command
some_long_running_calculation | second_command

Μια πιο αποδοτική προσέγγιση είναι να αποθηκεύσεις την έξοδο του υπολογισμού (χρησιμοποιώντας αντικατάσταση εντολών) και να χρησιμοποιήσεις here strings για να δώσεις είσοδο στις δύο επόμενες εντολές:

result=$( some_long_running_calculation )
first_command <<< "$result"
second_command <<< "$result"

Να μια εφαρμογή αυτού του παραδείγματος στον πραγματικό κόσμο:

  • αποθήκευσε την απάντηση JSON σε ένα ερώτημα REST API (που είναι σελιδοποιημένο),
  • δώσε τα δεδομένα JSON σε ένα πρόγραμμα jq για να αναλύσει τα αποτελέσματα και να τα γράψει σε ένα αρχείο, και στη συνέχεια
  • δώσε τα δεδομένα JSON σε ένα άλλο πρόγραμμα jq για να προσδιορίσεις το URL του επόμενου ερωτήματος.
# initialize the output CSV file
echo "ID,VALUE" > data.csv

url='https//example.com/api/query?page=1'

while true; do
  json=$( curl "$url" )

  # convert the results part of the response into CSV
  jq -r '.results[] | [.id, .value] | @csv' <<< "$json"

  # get the URL for the next page
  url=$( jq -r '.next_url // ""' <<< "$json" )
  if [[ "$url" == "" ]]; then
    break
  fi
done >> data.csv

Πρόσεξε τη θέση της ανακατεύθυνσης εξόδου. Όλη η έξοδος από τον βρόχο while θα προστεθεί στο αρχείο data.csv.

Τα heredocs και τα herestrings ως ανακατεύθυνση

Επειδή αυτά είναι απλώς μορφές ανακατεύθυνσης, μπορούν να συνδυαστούν με άλλες πράξεις ανακατεύθυνσης:

cat <<< END_OF_TEXT > output.txt
This is my important text.
END_OF_TEXT

awk '...' <<< "$my_var" >> result.csv

Συνοψίζοντας

Τα here documents (ή "heredocs") είναι ένας ευέλικτος και βολικός τρόπος να διαχειρίζεσαι πολυγραμμική είσοδο σε σενάρια Bash. Απλοποιούν τη διαδικασία ενσωμάτωσης κειμένου και δεδομένων απευθείας μέσα στα σενάριά σου, κάνοντάς τα πιο αυτοτελή και πιο ευανάγνωστα.

Τα here strings (ή "herestrings") είναι σαν τα here documents, αλλά προσφέρουν απλούστερη και πιο δυναμική σύνταξη.

Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα