Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม Bash

เชี่ยวชาญ Heredoc ใน Shell Scripting: คู่มือปฏิบัติ

Here Document (Heredoc) เป็น Input หรือ File Stream Literal ที่ถือว่าเป็น Special Block ของโค้ด Block นี้จะถูกส่งให้ Command ประมวลผล Heredoc มาจาก UNIX Shells พบได้ใน Linux Shells ยอดนิยมอย่าง sh, tcsh, ksh, bash, zsh, csh ภาษาโปรแกรมอื่นๆ เช่น Perl, Ruby, PHP ก็รองรับ Heredoc

โครงสร้างของ Heredoc

Heredoc ใช้ Angle Brackets 2 ตัว (<<) ตามด้วย Delimiter Token Delimiter Token เดียวกันจะใช้จบ Block โค้ด ทุกอย่างภายใน Delimiter ถือว่าเป็น Block ของโค้ด

ดูตัวอย่างด้านล่าง Redirect Block ไป Cat Command Delimiter ตั้งเป็น BLOCK จบด้วย BLOCK เดียวกัน

cat << BLOCK
Hello world
Today date is $(date +%F)
My home directory = ${HOME}
BLOCK

NOTE: ควรใช้ Delimiter Token เดียวกันเริ่ม Block และจบ Block

สร้าง Multiline Comments

ถ้าเขียน Bash บ้าง คุณรู้ว่า Bash โดย Default ไม่รองรับ Multiline Comments เหมือน C หรือ Java ใช้ HereDoc แก้ได้

นี่ไม่ใช่ Built-in Feature ของ Bash รองรับ Multi-line Comment แค่ Hack ถ้าไม่ Redirect Heredoc ไป Command ใด Interpreter จะอ่าน Block แค่นั้นและไม่ Execute อะไร

<< COMMENT
This is comment line 1
This is comment line 2
This is comment line 3
COMMENT
เชี่ยวชาญ Heredoc ใน Shell Scripting: คู่มือปฏิบัติ

จัดการ White Spaces

โดย Default Heredoc ไม่ Suppress White Space Characters (Tabs, Spaces) Override ได้ด้วยการเพิ่ม Dash (-) หลัง (<<) ตามด้วย Delimiter จะ Suppress Tab Spaces ทั้งหมด แต่ White Spaces จะไม่ Suppress

cat <<- BLOCK
This line has no whitespace.
This line has 2 white spaces at the beginning.
This line has a single tab.
This line has 2 tabs.
This line has 3 tabs.
BLOCK
เชี่ยวชาญ Heredoc ใน Shell Scripting: คู่มือปฏิบัติ

Variable และ Command Substitution

Heredoc รองรับ Variable Substitution Variables เป็น User-defined หรือ Environmental Variables

TODAY=$(date +%F)
cat << BLOCK1
# User defined variables
Today date is = ${TODAY}
# Environ Variables
I am running as = ${USER}
My home dir is = ${HOME}
I am using ${SHELL} as my shell
BLOCK1

เช่นกัน รัน Commands ใดๆ ภายใน Heredoc Code Block ได้

cat << BLOCK2
$(uname -a)
BLOCK2
เชี่ยวชาญ Heredoc ใน Shell Scripting: คู่มือปฏิบัติ เชี่ยวชาญ Heredoc ใน Shell Scripting: คู่มือปฏิบัติ

Escaping Special Characters

มีหลายวิธี Escape Special Characters ทั้ง Character Level และ Doc Level

Escape ตัวละตัว ใช้ Backslash (\)

cat << BLOCK4
\$(uname -a)
BLOCK4
cat << BLOCK5
Today date is = \${TODAY}
BLOCK5

Escape ทุก Special Characters ใน Block ใส่ Delimiter ใน Single Quotes, Double Quotes หรือ Prefix Delimiter ด้วย Backslash

cat << 'BLOCK1'
I am running as = ${USER}
BLOCK1
cat << "BLOCK2"
I am running as = ${USER}
BLOCK2
cat << \BLOCK3
I am running as = ${USER}
BLOCK3
เชี่ยวชาญ Heredoc ใน Shell Scripting: คู่มือปฏิบัติ

ตอนนี้เรารู้โครงสร้าง Heredoc และการทำงาน มาดูตัวอย่างเพิ่ม 2 พื้นที่ทั่วไปที่ใช้ Heredoc คือ รัน Block ของ Commands ผ่าน SSH และส่ง SQL Queries ผ่าน Heredoc

ตัวอย่างด้านล่าง พยายาม Execute Block ของโค้ดใน Remote Server ผ่าน SSH

เชี่ยวชาญ Heredoc ใน Shell Scripting: คู่มือปฏิบัติ

ตัวอย่างด้านล่าง ส่ง Select Statement ไป psql เชื่อม Database รัน Query นี่เป็น Alternative Way รัน Query ใน psql ภายใน Bash Script แทน Flag -f รัน .sql File

#!/usr/bin/env bash
UNAME=postgres
DBNAME=testing
psql --username=${UNAME} --password --dbname=${DBNAME} << BLOCK
SELECT * FROM COUNTRIES WHERE region_id = 4;
BLOCK
เชี่ยวชาญ Heredoc ใน Shell Scripting: คู่มือปฏิบัติ

ขอจบเท่านี้ มีอะไรทำได้กับ Heredoc มากกว่าที่แสดง หากมี Hack ที่มีประโยชน์ Post ใน Comment Section ให้ Readers ได้ประโยชน์