Στον προγραμματισμό με Bash, ένα "here document" (ή "heredoc") ανακατευθύνει πολλαπλές γραμμές εισόδου σε μια εντολή ή ένα πρόγραμμα, σαν να τις πληκτρολογούσες απευθείας στο τερματικό. Είναι ένα ισχυρό εργαλείο για να ενσωματώνεις πολυγραμμικό κείμενο μέσα στα σενάριά σου χωρίς να χρειάζεσαι εξωτερικά αρχεία ή περίπλοκους χειρισμούς συμβολοσειρών.
Οριοθέτης: ένα here document ξεκινά με τον τελεστή << ακολουθούμενο από μια λέξη-οριοθέτη (συχνά αποκαλούμενη "marker" ή "terminator").
Αυτός ο οριοθέτης μπορεί να είναι οποιαδήποτε λέξη διαλέξεις, αλλά συνηθίζεται να χρησιμοποιείς κάτι σαν EOF, END ή TEXT για σαφήνεια.
Για πιο ευανάγνωστο κώδικα, μπορείς να χρησιμοποιήσεις κάτι περιγραφικό ως οριοθέτη, για παράδειγμα END_INSTALLATION_INSTRUCTIONS.
Περιεχόμενο: μετά το αρχικό << DELIMITER, γράφεις το περιεχόμενο που θέλεις να ανακατευθύνεις.
Αυτό μπορεί να είναι πολλαπλές γραμμές κειμένου, κώδικας ή οτιδήποτε άλλο.
Τερματισμός: το here document τελειώνει όταν η λέξη-οριοθέτης εμφανιστεί ξανά σε μια γραμμή μόνη της, χωρίς κενά πριν ή μετά.
command << DELIMITER
Content line 1
Content line 2
...
Content line N
DELIMITER
<< DELIMITER και το τελικό DELIMITER.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 εμφανίζει το περιεχόμενο που έλαβε.wc -l << END
Line 1
Line 2
Line 3
END
Έξοδος:
3
Εδώ, το wc -l μετράει τον αριθμό των γραμμών.
Το here document παρέχει τις τρεις γραμμές ως είσοδο.
Το σενάριο:
#!/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))
Αν χρησιμοποιήσεις το <<- (με παύλα στο τέλος) αντί για το <<, το 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.
Ο συγγραφέας δεν συνιστά αυτή τη χρήση. Ενώ μπορεί να βελτιώσει την αναγνωσιμότητα του σεναρίου,
Μια τυπική χρήση μπορεί να είναι η παροχή κάποιου κειμένου βοήθειας:
#!/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 strings (ή "herestrings") παρέχουν είσοδο σε μια εντολή.
Ωστόσο, ενώ τα heredocs δίνονται ως ένα μπλοκ κειμένου, οι herestrings δίνονται ως μία μόνο συμβολοσειρά κειμένου.
Τα here strings χρησιμοποιούν τη σύνταξη <<< "text".
tr 'a-z' 'A-Z' <<< "upper case this string"
Έξοδος:
UPPER CASE THIS STRING
Σε αντίθεση με τα heredocs, δεν απαιτείται οριοθέτης τερματισμού.
Μπορείς να χρησιμοποιήσεις μια σωλήνωση αντί για ένα 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"
Να μια εφαρμογή αυτού του παραδείγματος στον πραγματικό κόσμο:
# 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.
Επειδή αυτά είναι απλώς μορφές ανακατεύθυνσης, μπορούν να συνδυαστούν με άλλες πράξεις ανακατεύθυνσης:
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, αλλά προσφέρουν απλούστερη και πιο δυναμική σύνταξη.