GNU/Linux >> Belajar Linux >  >> Linux

Cara membuat dokumen dengan skrip Bash

Terkadang Anda perlu membuat dokumen multi-baris dengan struktur bersarang yang kompleks, seperti YAML atau HTML, dari dalam skrip Bash. Anda dapat melakukannya dengan menggunakan beberapa fitur Bash khusus, seperti dokumen di sini . "di sini doc" adalah kode atau blok teks yang dapat diarahkan ke skrip atau program interaktif. Pada dasarnya, skrip Bash menjadi dokumen di sini saat dialihkan ke perintah, skrip, atau program interaktif lain.

Artikel ini menjelaskan cara:

  • Gunakan larik, kamus, dan penghitung
  • Bekerja dengan berbagai jenis komentar
  • Buat dokumen YAML dan HTML
  • Kirim email dengan teks dan lampiran

[ Unduh sekarang:Panduan sysadmin untuk skrip Bash. ]

Mendokumentasikan skrip

Penting untuk mengomentari skrip Anda, dan Anda dapat membuat komentar satu baris dengan # , atau Anda dapat memiliki komentar multi-baris dengan menggunakan kombinasi : dan <<ANYTAG .

Misalnya:

# This is a simple comment
: <<COMMENT

This is a multi-line comment
Very useful for some complex comments

COMMENT 

Fungsi bantuan untuk skrip Anda ini adalah contoh lain yang berguna:

#!/bin/bash
SCRIPT=$(/usr/bin/basename $0)|| exit 100
export SCRIPT
function help_me {
    /usr/bin/cat<<EOF

$SCRIPT -- A cool script that names and oh wait...
------------------------------------------------------
$SCRIPT --arg1 \$VALUE --arg2 \$VALUE2

EOF

help_me
}

# To use the help function just call help
help_me 

Format multi-baris cukup berguna dengan sendirinya, terutama saat mendokumentasikan skrip yang kompleks. Namun, ada perubahan bagus untuk menggunakan dokumen di sini yang mungkin pernah Anda lihat sebelumnya:

$ /usr/bin/cat<<EOF>$HOME/test_doc.txt
Here is a multi-line document that I want to save.
Note how I can use variables inside like HOME=$HOME.

EOF 

Berikut yang tertulis dalam file tersebut:

$ /usr/bin/cat $HOME/test_doc.txt
Here is a multi-line document that I want to save.
Note how I can use variables inside like HOME=/home/josevnz. 

Sekarang saya akan beralih ke hal lain sehingga Anda dapat menerapkan pengetahuan ini.

[ Untuk kiat Bash lainnya, unduh Lembar Cheat Scripting Bash Shell ini ]

Menggunakan array dan kamus untuk menghasilkan file YAML inventaris yang memungkinkan

Misalnya Anda memiliki file CSV berikut dengan daftar host di setiap baris yang berisi server atau desktop:

# List of hosts, tagged by group
macmini2:servers
raspberrypi:servers
dmaf5:desktops
mac-pro-1-1:desktops 

Anda ingin mengonversi daftar ke file inventaris YAML yang Dimungkinkan berikut:

--- all:   children:     servers:       hosts:         macmini2:         raspberrypi:       vars:         description: Linux servers for the Nunez family     desktops:       hosts:         dmaf5:         mac-pro-1-1:       vars:         description: Desktops for the Nunez family        

Batasan ekstra:

  • Setiap jenis sistem (desktop atau server) akan memiliki variabel berbeda yang disebut description . Menggunakan larik dan larik asosiatif serta penghitung memungkinkan Anda memenuhi persyaratan ini.
  • Skrip akan gagal jika pengguna tidak memberikan semua tag yang benar. Inventaris yang tidak lengkap tidak dapat diterima. Untuk persyaratan ini, penghitung sederhana akan membantu.

Skrip ini mencapai tujuan:

#!/bin/bash
:<<DOC
Convert a file in the following format to Ansible YAML:
# List of hosts, tagged by group
macmini2:servers
raspberrypi:servers
dmaf5:desktops
mac-pro-1-1:desktops
DOC
SCRIPT="$(/usr/bin/basename "$0")"|| exit 100
function help {
    /usr/bin/cat<<EOF
Example:
$SCRIPT $HOME/inventory_file.csv servers desktops
EOF
}

# We could use a complicated if-then-else or a case ... esac 
# to handle the tag description logic
# with an Associate Array is very simple
declare -A var_by_tag
var_by_tag["desktops"]="Desktops for the Nunez family"
var_by_tag["servers"]="Linux servers for the Nunez family"

function extract_hosts {
    tag=$1
    host_file=$2
    /usr/bin/grep -P ":$tag$" "$host_file"| /usr/bin/cut -f1 -d':'
    test $? -eq 0 && return 0|| return 1
}
# Consume the host file
hosts_file=$1
shift 1
if [ -z "$hosts_file" ]; then
    echo "ERROR: Missing host file!"
    help
    exit 100
fi

if [ ! -f "$hosts_file" ]; then
    echo "ERROR: Cannot use provided host file: $hosts_file"
    help
    exit 100
fi
# Consume the tags
if [ -z "$*" ]; then
    echo "ERROR: You need to provide one or more tags for the script to work!"
    help
    exit 100
fi
: <<DOC
Generate the YAML
The most annoying part is to make sure the indentation is correct. YAML depends entirely on proper indentation.
The idea is to iterate through the tags and perform the proper actions based on each.
DOC
for tag in "$@"; do # Quick check for tag description handling. Show the user available tags if that happens
    if [ -z "${var_by_tag[$tag]}" ]; then
        echo "ERROR: I don't know how to handle tag=$tag (known tags=${!var_by_tag[*]}). Fix the script!"
        exit 100
    fi
done
/usr/bin/cat<<YAML
---
all:
  children:
YAML
# I do want to split by spaces to initialize my array, this is OK:
# shellcheck disable=SC2207
for tag in "$@"; do
    /usr/bin/cat<<YAML
    $tag:
      hosts:
YAML
    declare -a hosts=($(extract_hosts "$tag" "$hosts_file"))|| exit 100
    host_cnt=0 # Declare your counter
    for host in "${hosts[@]}"; do
        /usr/bin/cat<<YAML
        $host:
YAML
        ((host_cnt+=1)) # This is how you increment a counter
    done
    if [ "$host_cnt" -lt 1 ]; then
        echo "ERROR: Could not find a single host with tag=$tag"
        exit 100
    fi
    /usr/bin/cat<<YAML
      vars:
        description: ${var_by_tag[$tag]}
YAML
done 

Berikut tampilan outputnya:

all:   children:     servers:       hosts:         macmini2:         raspberrypi:       vars:         description: Linux servers for the Nunez family     desktops:       hosts:         dmaf5:         mac-pro-1-1:       vars:         description: Desktops for the Nunez family

Cara yang lebih baik adalah dengan membuat inventaris dinamis dan membiarkan buku pedoman Ansible menggunakannya. Untuk menjaga agar contoh tetap sederhana, saya tidak melakukannya di sini.

Mengirim email HTML dengan lampiran YAML

Contoh terakhir akan menunjukkan kepada Anda cara menyalurkan dokumen di sini ke Mozilla Thunderbird (Anda dapat melakukan sesuatu yang mirip dengan /usr/bin/mailx ) untuk membuat pesan dengan dokumen HTML dan lampiran:

#!/bin/bash
:<<HELP
Please take a look a the following document so you understand the Thunderbird command line below:
http://kb.mozillazine.org/Command_line_arguments_-_Thunderbird
HELP
declare EMAIL
EMAIL=$1
test -n "$EMAIL"|| exit 100
declare ATTACHMENT
test -n "$2"|| exit 100
test -f "$2"|| exit 100
ATTACHMENT="$(/usr/bin/realpath "$2")"|| exit 100
declare DATE
declare TIME
declare USER
declare KERNEL_VERSION
DATE=$(/usr/bin/date '+%Y%m%d')|| exit 100
TIME=$(/usr/bin/date '+%H:%M:%s')|| exit 100
USER=$(/usr/bin/id --real --user --name)|| exit 100
KERNEL_VERSION=$(/usr/bin/uname -a)|| exit 100

/usr/bin/cat<<EMAIL| /usr/bin/thunderbird -compose "to='$EMAIL',subject='Example of here documents with Bash',message='/dev/stdin',attachment='$ATTACHMENT'"

<!DOCTYPE html>
<html>
<head>
<style>
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}
</style>
</head>
<body>
<h2>Hello,</p> <b>This is a public announcement from $USER:</h2>
<table>
  <tr>
    <th>Date</th>
    <th>Time</th>
    <th>Kernel version</th>
  </tr>
  <tr>
    <td>$DATE</td>
    <td>$TIME Rovelli</td>
    <td>$KERNEL_VERSION</td>
  </tr>
</table>
</body>
</html>
EMAIL 

Kemudian Anda dapat memanggil skrip mailer:

$ ./html_mail.sh [email protected] hosts.yaml 

Jika semuanya berjalan seperti yang diharapkan, Thunderbird akan membuat email seperti ini:

Menutup

Untuk rekap, Anda telah mempelajari cara:

  • Gunakan struktur data yang lebih canggih seperti array dan array asosiatif untuk membuat dokumen
  • Gunakan penghitung untuk melacak acara
  • Gunakan dokumen di sini untuk membuat dokumen YAML, petunjuk bantuan, HTML, dll.
  • Kirim email dengan HTML dan YAML

Bash dapat digunakan untuk membuat dokumen kecil yang tidak rumit. Jika Anda berurusan dengan dokumen besar atau kompleks, Anda mungkin lebih baik menggunakan bahasa skrip lain seperti Python atau Perl untuk mendapatkan hasil yang sama dengan sedikit usaha. Selain itu, jangan pernah meremehkan pentingnya debugger nyata saat menangani pembuatan dokumen yang rumit.


Linux
  1. Cara Membuat Database di MySQL dengan MySQL Workbench

  2. Cara membuat skrip Bash menggunakan variabel eksternal dan skrip yang disematkan

  3. Cara membuat lonjakan CPU dengan perintah bash

  1. Cara membuat dokumen LaTeX dengan Emacs

  2. Cara Membuat atau Menambahkan Indeks di MySQL Dengan Contoh

  3. Bagaimana Cara Membuat Vm Dari Awal Dengan Virsh?

  1. Cara Menulis Skrip Bash dengan Contoh

  2. Cara Membuat Backup dengan Perintah tar di Linux

  3. Cara Membuat Bash Alias ​​​​