แนวทางปฏิบัติที่ดีที่สุดในการสร้าง Shell Script ใน GNU / Linux

โดยปกติเมื่อคุณเริ่มทำงานกับไฟล์ พื้นที่การดูแลเซิร์ฟเวอร์ที่มีระบบปฏิบัติการ GNU / Linux และ / หรือ Unixหนึ่งพบว่าตัวเอง (ใบหน้า) ทำงานในสภาพแวดล้อมที่มักจะมี งานตามกำหนดเวลามากมายที่ผู้ดูแลระบบคนอื่นเขียนไว้ และในบางจุดเราต้อง จัดการ (ดูแลระบบ) สำหรับ แก้ไขปัญหาปรับปรุงและ / หรือกำจัดเพื่อให้สอดคล้องกับข้อกำหนดใหม่ของสถาบัน เขาทำงานที่ไหน จึงไม่แปลกที่ใหม่ ๆ ผู้ดูแลระบบ ในที่ทำงานใด ๆ คุณต้องเผชิญกับงานที่ยุ่งยากในการทำความเข้าใจบางส่วนของ เชลล์สคริปต์ สร้างโดยผู้อื่น SysAdmin เก่าซึ่งเขียนไม่ดีหรืออยู่ในโครงสร้างเชิงตรรกะหรือการเขียนไม่เข้าใจง่ายหรือในกรณีที่เลวร้ายที่สุดคือมีคำสั่งคำสั่งผิดปกติเก่าไม่มีประสิทธิภาพหรือเขียนในลักษณะที่น่าอึดอัดและสับสน

การเขียนสคริปต์เชลล์

ในขณะที่ การแก้สคริปต์ที่เขียนไม่ดี เป็นความรำคาญชั่วขณะเสมอสิ่งนี้สอนใคร ๆ SysAdmin ที่ดี สิ่งที่สำคัญ หากกำลังจะสร้างไฟล์ เชลล์สคริปต์ ที่จะใช้เกินวันนี้จะดีกว่าเสมอ เขียนด้วยวิธีที่เป็นมืออาชีพและได้มาตรฐานดังนั้นเมื่อเวลาผ่านไปทุกคนหรือตัวเองสามารถทำได้ด้วยไฟล์ ความพยายามและความรู้เพียงเล็กน้อยบรรลุความเข้าใจและการบริหารงานในเวลาขั้นต่ำ

ดังนั้นหลังจากชุดสิ่งพิมพ์ที่ใช้งานได้จริงบน "เรียนรู้เชลล์สคริปต์" ที่เราตรวจสอบสคริปต์ที่ใช้งานได้จริงด้วยคำสั่งที่เรียบง่ายและเป็นพื้นฐานเราจะเริ่มต้นด้วยซีรีส์ใหม่ที่เรียกว่า "แนวทางปฏิบัติที่ดีที่สุดในการสร้าง Shell Script ใน GNU / Linux", ซึ่งเราจะเน้นอย่างละเอียดในแต่ละแง่มุมเล็ก ๆ น้อย ๆ ของมันและเหตุผลของหลาย ๆ สิ่งนั่นคือเราจะพูดถึงเคล็ดลับบางอย่างที่จะทำให้เราสร้างสคริปต์ได้ดีขึ้น แต่ไม่มากสำหรับตัวเราเอง แต่สำหรับคนต่อไป (SysAdmin) ว่า ต้องจัดการพวกเขา ดังนั้นคุณจึงไม่ต้องผ่านงานที่น่าเบื่อและยากในการค้นหาว่าฉันเขียนโค้ดอะไรอย่างไรทำไมและทำไมจึงใช้งานไม่ได้อีกต่อไป

ในการนี​​้ โพสต์แรก (1) ของซีรีส์ใหม่นี้ "แนวทางปฏิบัติที่ดีที่สุดสำหรับ Shell Script ที่ดีสำหรับ GNU / Linux" เราจะพูดถึงสิ่งที่ควรไปหรือควรไปในไฟล์ ส่วนหัวเชลล์สคริปต์

=======================================
HEADER - คำเชิญของเชลล์
=======================================

#! / path / ตีความ [พารามิเตอร์อาร์กิวเมนต์]

บรรทัดบนสุดเป็นโครงสร้างพื้นฐานที่เรียกใช้เชลล์สคริปต์สำหรับ GNU / Linux องค์ประกอบสามารถอธิบายได้ดังนี้:

#! => sha-bang

Sha-Bang (#!) ที่ด้านบนของสคริปต์ที่สร้างหรือที่จะสร้างคือไฟล์ สคริปต์ที่บอกระบบปฏิบัติการของเราว่าไฟล์ของเราเป็นชุดคำสั่งที่จะถูกป้อน (จะถูกแปลความหมาย) โดยตัวแปลคำสั่งที่ระบุไว้ข้างหลัง คู่อักขระ #! จริงๆแล้วมันคือ เลขวิเศษ สองไบต์ซึ่งเป็นเครื่องหมายพิเศษที่ กำหนดประเภทไฟล์และในกรณีของเรา เชลล์สคริปต์ที่เรียกใช้งานได้. ทันทีหลังจากที่ Sha-bang มาถึงชื่อของ เส้นทางที่ล่ามที่จะดำเนินการตั้งอยู่พร้อมชื่อของล่ามดังกล่าว. กล่าวอีกนัยหนึ่งนี่คือเส้นทางไปยังโปรแกรมที่ตีความคำสั่งในสคริปต์ไม่ว่าจะเป็นล่ามภาษาโปรแกรมหรือยูทิลิตี้ จากนั้นเชลล์นี้จะรันคำสั่งในสคริปต์โดยเริ่มจากด้านบนสุด (บรรทัดหลัง sha-bang) และละเว้นความคิดเห็นใด ๆ บาง sha ปัง พวกเขาสามารถ:

# / bin / sh
#! / bin / ทุบตี
#! / usr / bin / perl
#! / usr / bin / tcl
#! / bin / sed -f
#! / usr / awk -f

แต่ละบรรทัดที่อธิบายไว้ข้างต้น (ดังตัวอย่าง) เรียกใช้เชลล์ที่แตกต่างกัน เส้น bin / sh /เรียกใช้ไฟล์ เปลือก โดยค่าเริ่มต้น (ทุบตีบนระบบปฏิบัติการ GNU / Linux) หรืออื่น ๆ ที่คล้ายกัน การใช้ # / bin / shค่าเริ่มต้นของ บอร์นเชลล์ ในรูปแบบเชิงพาณิชย์ส่วนใหญ่ของระบบปฏิบัติการที่ใช้ UNIX จะทำให้สคริปต์ถูกสร้างขึ้น พกพาไปยังระบบปฏิบัติการอื่นที่ไม่ใช่ Linux อย่างถูกต้องแต่คล้ายหรืออิงกับมันหรือ UNIX แม้ว่าสิ่งนี้จะเสียสละคุณสมบัติเฉพาะของ BASH อย่างไรก็ตามลำดับ "#! / บิน / ช" เป็นไปตามบรรทัดฐาน POSIX sh มาตรฐาน.

สังเกตได้ว่า เส้นทางที่กำหนดใน sha-bang ต้องถูกต้องมิฉะนั้นมักจะเป็นข้อความแสดงข้อผิดพลาด "ไม่พบคำสั่ง"มันจะเป็นผลลัพธ์เดียวของการเรียกใช้สคริปต์ จำคู่อักขระ »#! « สามารถละเว้นได้หากสคริปต์ประกอบด้วยชุดคำสั่งทั่วไปของระบบปฏิบัติการเท่านั้นนั่นคือโดยไม่ใช้คำสั่งเชลล์ภายใน และโปรดทราบอีกครั้งว่า » #! / bin / sh « เรียกใช้ตัวแปลเชลล์ดีฟอลต์ซึ่งมีค่าเริ่มต้นเป็น » #! / bin / ทุบ« ในทีมกับเขา ระบบปฏิบัติการ GNU / Linux.

เกี่ยวกับอาร์กิวเมนต์มีหลายอย่างที่สามารถใช้ได้ แต่ที่พบบ่อยที่สุดคือ: » -E «. ซึ่งทำให้สคริปต์ ตรวจสอบข้อผิดพลาดในการดำเนินการของคำสั่งใด ๆo (บรรทัดการดำเนินการ) และถ้าเป็นบวก บังคับให้หยุดและออกโดยทั่วไปคือ » -F « สำหรับ ระบุว่าจะโหลดสคริปต์ใด และหนึ่งในสิ่งที่หายากที่สุดคือ » -Rm « ที่ดำเนินการลบเมื่อการดำเนินการเสร็จสิ้น เป็นไปได้ที่จะระบุในไฟล์ sha ปัง ถึง อาร์กิวเมนต์เดียว (พารามิเตอร์) หลังชื่อของโปรแกรมที่จะดำเนินการ

และสุดท้ายบอกสคริปต์ ตัวแปรส่วนกลางที่คุณจะใช้ในส่วนสำคัญของโค้ดของคุณสำหรับการตรวจสอบความถูกต้องของเหตุการณ์เช่นเส้นทางการดำเนินการผู้ใช้ที่ได้รับอนุญาตชื่อสคริปต์และอื่น ๆ และปิดท้ายด้วย ข้อมูลของโปรแกรมผู้สร้างองค์กรและอื่น ๆ รวมถึงการอนุญาตให้ใช้สิทธิ์ที่ใช้กับโปรแกรม

คำแนะนำของฉัน (แนวทางปฏิบัติที่ดีที่สุด) เพื่อเลือก Sha-Bang ที่ดีที่สุด และมุ่งหน้าไปที่ เชลล์สคริปต์ เสียง:

#! / usr / bin / env bash

ทำไมต้องใช้คำสั่ง » Env « เราระบุไปยังระบบปฏิบัติการว่าล่ามจะใช้กับเส้นทางที่แน่นอนที่ระบุไว้ภายในโดยค่าเริ่มต้นซึ่งช่วยให้เรามี sha ปัง ที่เพิ่มความสะดวกในการพกพาเพราะไม่ใช่ทั้งหมด OS GNU / ลินุกซ์ ล่ามหรือโปรแกรมมีเส้นทางเดียวกัน และไม่มีข้อโต้แย้งเพราะจะดีกว่าที่จะใช้คำสั่ง ชุดเพราะกับเขาเราทำได้ ตรวจสอบข้อผิดพลาดทั่วไป (-e) หรือเฉพาะ (+ x / -x)หรือสำหรับ ล้างค่าที่ตั้งล่วงหน้าทั่วโลกสำหรับตัวแปรสภาพแวดล้อม (-i) หรือเฉพาะ (-u / –unset). และสุดท้ายถึง ดำเนินการเฉพาะ (- o) การดำเนินการเสริม ภายในสคริปต์

ดังนั้น HEADER ที่ฉันแนะนำคือ:

#! / usr / bin / env bash
# ระบุตัวแปล bash ด้วยพา ธ สัมบูรณ์โดยระบบปฏิบัติการ

set -o ยกขึ้น
# เพื่อบอกให้สคริปต์หยุดและปิดเมื่อคำสั่งหรือบรรทัดการดำเนินการล้มเหลว

set -o คำนาม
# เพื่อบอกให้สคริปต์หยุดและปิดเมื่อสคริปต์พยายามใช้ตัวแปรที่ไม่ได้ประกาศ

ชุด -o pipefail
# เพื่อรับสถานะการออกของคำสั่งสุดท้ายที่ส่งคืนรหัสทางออกที่ไม่ใช่ศูนย์

# ชุด -o xtrace
# เพื่อติดตามสิ่งที่วิ่ง มีประโยชน์สำหรับการดีบัก เปิดใช้งานเพื่อตรวจสอบข้อผิดพลาดเท่านั้น

อย่าลืมปฏิบัติตามคำแนะนำเหล่านี้เพิ่มเติม:

01.- เยื้องรหัสของคุณ: การทำให้รหัสของคุณชัดเจนเป็นสิ่งสำคัญมากและเป็นสิ่งที่หลายคนดูเหมือนจะลืมไปเช่นกัน พยายามสร้างการเยื้องที่จำเป็นเพื่อรับรู้โครงสร้างเชิงตรรกะที่ดีในสายตา

02.- เพิ่มช่องว่างระหว่างส่วนรหัส: สิ่งนี้สามารถช่วยให้เข้าใจโค้ดได้มากขึ้นเนื่องจากการเว้นระยะห่างตามโมดูลหรือส่วนต่างๆช่วยให้โค้ดอ่านง่ายและเข้าใจง่าย

03.- แสดงความคิดเห็นเกี่ยวกับรหัสให้มากที่สุด: ที่ด้านบน (หรือด้านล่าง) ของคำสั่งแต่ละคำสั่ง (บรรทัดการดำเนินการ) หรือส่วนของโค้ดเหมาะอย่างยิ่งที่จะเพิ่มคำอธิบายของฟังก์ชันของสคริปต์เพื่ออธิบายสิ่งที่เกิดขึ้นภายในโค้ดเอง

04.- สร้างตัวแปรด้วยชื่อที่สื่อความหมายของฟังก์ชัน: กำหนดชื่อตัวแปรที่สื่อความหมายซึ่งระบุฟังก์ชันที่จะสร้างอย่างชัดเจน แม้ว่าคุณจะสร้างตัวแปรชั่วคราวที่จะไม่ใช้นอกบล็อกโค้ดเดียว แต่ก็ยังดีที่จะใส่ชื่อที่อธิบายโดยนัย (อย่างเป็นกลาง) เพื่ออธิบายค่าหรือฟังก์ชันที่จัดการ

05.- ใช้ไวยากรณ์ VARIABLE = $ (command) สำหรับการทดแทนคำสั่ง: หากคุณต้องการสร้างตัวแปรที่มีค่ามาจากคำสั่งอื่นมีสองวิธีในการทำ bash ด้วย แบคทิคนั่นคือกับตัวละคร , อจ: VARIABLE = `command -options parameters`แต่มันเลิกใช้แล้วดังนั้นไวยากรณ์ VARIABLE = $ (คำสั่ง) เป็นวิธีที่ทันสมัยที่สุดได้รับการยอมรับและแนะนำ ไม่ -> วันที่ = `วันที่ +% F` / ใช่ -> วันที่ = $ (วันที่ +% F)

06.- ใช้โมดูล Superuser และ Authorized User Validation และ / หรือตัวแปรที่มีหรือไม่มีรหัสผ่าน: เพื่อเพิ่มระดับความปลอดภัยหากจำเป็น

07.- ใช้โมดูลและ / หรือตัวแปรของการตรวจสอบความถูกต้องของระบบปฏิบัติการ (Distro, Version, Architecture): เพื่อป้องกันการใช้งานบนแพลตฟอร์มที่ไม่เหมาะสม

08.- ใช้โมดูล (ขั้นตอน / ส่วน) เพื่อยืนยันการดำเนินการของการดำเนินการที่สำคัญหรือแบทช์ (โมดูล / ฟังก์ชัน): เพื่อลดความผิดพลาดอันเนื่องมาจากการด้นสดหรือความประมาท

09.- จัดเตรียมอินเทอร์เฟซที่ใช้งานง่าย (ใช้งานง่าย): โดย Terminal มีเมนูและสีด้วย บทสนทนา และ อินเทอร์เฟซแบบกราฟิกสำหรับผู้ใช้ขั้นพื้นฐานที่มี Zenity, Gxmessage และถ้าเป็นไปได้ให้ใช้การสนับสนุนของการแจ้งเตือนด้วยเสียงที่ระบุเหตุการณ์ที่จดจำได้ตามเสียง ฉันพยายามให้มากที่สุดเท่าที่จะทำได้ ทำงานได้ทั้งสองวิธีเพียงแค่เปิดใช้งานและปิดใช้งานตัวเลือก / โมดูล / ฟังก์ชัน

10.- รวมโมดูลต้อนรับและอำลา (ข้อความ): ในกรณีที่จำเป็นเพื่อเพิ่มการโต้ตอบกับผู้ใช้

11.- รวมโมดูลการตรวจสอบการดำเนินการสองครั้ง: สร้างไฟล์ล็อกเพื่อป้องกันไม่ให้เรียกใช้งานมากกว่า 1 ครั้งในเวลาเดียวกัน

12.- กำหนดขนาดของสคริปต์ด้วยฟังก์ชันภายนอกและ / หรือโมดูล: หากสคริปต์มีขนาดใหญ่มากให้แบ่งโค้ดโดยใช้ฟังก์ชันหรือแบ่งออกเป็นสคริปต์ขนาดเล็กที่เรียกใช้ผ่านสคริปต์หลัก

13.- การร้องขออย่างชัดเจนและชัดเจนในการเรียกไปยังล่ามอื่น ๆ (ภาษาโปรแกรม) ภายในสคริปต์: เชิญพวกเขาอย่างชัดเจนโดยบรรทัดหรือโมดูล

ตัวอย่าง:

# ================================================== #
#!/bin/bash
#Llamando a un interprete externo a BASH
echo 'El siguiente texto será mostrado por el interprete de PERL'
perl -e 'print "Este texto es mostrado por un script PERL embebido.\n";'
exit 0
# ==================================================#
# ==================================================# 
#!/bin/bash #Llamando al interprete de Python. 
echo 'El siguiente es un script de python:'
echo print "Hola, mundo!" | tee $HOME/.testpythonbash.py
python $HOME/.testpythonbash.py exit 0
# ==================================================#

# ======================================================= #
#!/bin/bash
# bash-y-perl.sh

echo "Saludos desde la parte BASH del script."
# Es posible añadir mas comandos BASH aqui.

exit 0
# Fin de la parte BASH del script.

###########################################################

#!/usr/bin/perl
# Esta parte del script se invoca con la opcion -x.

print "Saludos desde la parte PERL del script.\n";
# Podemos añadir mas comandos PERL aqui.

# Fin de la parte PERL del script.
# ======================================================= #
 

ในสิ่งพิมพ์ในอนาคตเราจะขยายรายละเอียดเพิ่มเติมเกี่ยวกับแนวปฏิบัติแต่ละข้อที่อธิบายไว้ข้างต้น

และหากคุณรู้จักแนวทางปฏิบัติที่ดีอื่น ๆ ของตนเองหรือของผู้อื่นอย่าลังเลที่จะแสดงความคิดเห็นเพื่อรวบรวมบทสรุปที่สมบูรณ์ยิ่งขึ้น!

จนกว่าจะมีการตีพิมพ์ชุดใหม่นี้ในครั้งต่อไป


แสดงความคิดเห็นของคุณ

อีเมล์ของคุณจะไม่ถูกเผยแพร่ ช่องที่ต้องการถูกทำเครื่องหมายด้วย *

*

*

  1. ผู้รับผิดชอบข้อมูล: Miguel ÁngelGatón
  2. วัตถุประสงค์ของข้อมูล: ควบคุมสแปมการจัดการความคิดเห็น
  3. ถูกต้องตามกฎหมาย: ความยินยอมของคุณ
  4. การสื่อสารข้อมูล: ข้อมูลจะไม่ถูกสื่อสารไปยังบุคคลที่สามยกเว้นตามข้อผูกพันทางกฎหมาย
  5. การจัดเก็บข้อมูล: ฐานข้อมูลที่โฮสต์โดย Occentus Networks (EU)
  6. สิทธิ์: คุณสามารถ จำกัด กู้คืนและลบข้อมูลของคุณได้ตลอดเวลา

  1.   แม็กซ์ j rodriguez dijo

    แค่รายละเอียดเดียวมันคือ "shebang" 😛
    โพสต์ที่ดีมากแนวทางปฏิบัติที่ดีในระยะยาวช่วยสร้างมาตรฐานได้เสมอ

  2.   หนึ่งที่ผ่านมาที่นี่ dijo

    Bash ไม่ใช่เชลล์เริ่มต้นสำหรับการแจกแจงทั้งหมดดังนั้นลิงก์สัญลักษณ์ / bin / sh จึงไม่ชี้ไปที่ bash เสมอไป ใน Debian ตัวอย่างเช่น (และฉันถือว่า Ubuntu):
    $ ls -l / bin / sh
    lrwxrwxrwx 1 root root 4 aza 8 2014 / bin / sh -> dash
    เชลล์เริ่มต้นดังนั้นบน Debian จึงเป็นเส้นประ ดูที่นี่: https://wiki.debian.org/Shell

  3.   นิรนาม dijo

    เคล็ดลับในการรู้จักเชลล์ที่ใช้งาน:

    ก้อง $ 0
    ก้อง $ SHELL
    env | grep เชลล์

  4.   Jose Albert dijo

    คุณพูดถูกจริงๆ! ฉันทดสอบกับ DEBIAN 9 และ Kali Linux 2.0 แล้วมันก็จริง! พาคุณไป ยิ่งไปกว่านั้นคือคำแนะนำของ: #! / usr / bin / env bash หากเป็นเชลล์ที่คุณต้องการใช้

    และคุณพูดถูกแล้วว่ามันคือ shebang แต่ในบางเว็บไซต์ (วรรณกรรมทางเทคนิค) พวกเขาเรียกมันว่า shabang หรือคำอื่น ๆ ด้วยเหตุนี้ฉันจึงสับสน ตัวอย่าง:

    ในการคำนวณ Shebang คือลำดับอักขระที่ประกอบด้วยเครื่องหมายหมายเลขอักขระและเครื่องหมายอัศเจรีย์ (#!) ที่จุดเริ่มต้นของสคริปต์ เรียกอีกอย่างว่า sha-bang, [1] [2] hashbang, [3] [4] pound-bang, [5] หรือ hash-pling

    เริ่มต้นที่: https://en.wikipedia.org/wiki/Shebang_%28Unix%29

    Y บทที่ 2. เริ่มต้นด้วย Sha-Bang
    เริ่มต้นที่: http://www.tldp.org/LDP/abs/html/sha-bang.html

  5.   Jose Albert dijo

    นอกจากนี้: basename $ 0