Bash Script
รวมข้อมูลที่น่าสนใจไว้กันลืมนะครับ เพราะฉะนั้นอาจจะไม่มีอะไรเรียงตามลำดับซักเท่าไหร่นัก ส่วนพวกข้อมูลพื้นฐานน่าจะหาได้ทั่วไปนะครับ
- ก่อนอื่นการทำ Bash Script อย่าลืมใส่บรรทัดนี้ไว้บรรทัดแรกต้นไฟล์นะครับ
#!/bin/bash
- คำสั่งเรียกใช้ส่วนมากจะเหมือนที่ใช้ใน terminal ของลินุกซ์นะครับ เพียงแต่ถ้าจะเอาเข้าใส่ตัวแปรก็ตั้งชื่อ
variable = $(
command line)
นะครับ โดยที่
variable
คือชื่อแปรที่เราตั้ง ส่วน
command line
คือคำสั่งทั่วไปที่เราใช้กับ terminal นั้นละครับ
- คำสั่งให้รอเวลาก่อนจะทำงานคำสั่งอื่นๆ นะครับ sleep (number)(suffix) เช่น sleep 1m, sleep 6h, sleep 7d นะครับ โดยที่ suffix คือ m (นาที) h(ชั่วโมง) d (วัน) นะครับ
-
การเรียกใช้ Script อื่นให้ทำงาน ใช้คำสั่งตามนี้นะครับ
#!/bin/bash
MyScript="home/ NameUser/ MyScript.sh "
"$ MyScript"
โดยส่วนที่ตัวอักษรสีม่วง แก้ให้ตรงกับ Path ของไฟล์ในเครื่องเรานะครับ ส่วน MyScript คือชื่อของ Script ที่เราจะเรียกใช้นั้นเอง ซึ่งจริงๆ จะยัด path ของ Script เราเข้าไปข้างใน " " เลยก็ได้ครับ แต่แบบนี้จะดีกว่าเวลาโค้ดเราเริ่มเยอะ มันจะแก้ไขได้ง่าย (ใช้เรียก Script ของภาษาอื่นได้ด้วยนะครับ แต่ต้องคลิ๊กขวาเข้า Properties > Permission > ติ๊กถูกที่ Execute หรือ chmod ให้สิทธิ์ในการรันไฟล์ที่เราจะเรียกก่อนนะครับ)
- การโหลด Module ก่อนอื่นต้องเปลี่ยนคำสั่งรัน Script ที่จะใช้ใน Terminal ก่อนนะครับ จาก sh (PathFile+NameFile) เป็น bash (PathFile+NameFile) แทนนะครับ (หรือ ./(PathFile+NameFile) ก็ได้ แต่ต้อง
กำหนดสิทธิ์ให้มันรันได้ก่อน โดย ./ จะเริ่มต้นที่ path
home/
NameUser
/
ให้เลยนะครับ) ส่วนคำสั่งที่ใช้อ้างอิงถึงคือ
#!/bin/bash
module load home/ NameUser/ FileName
โดยส่วนที่ตัวอักษรสีม่วง แก้ให้ตรงกับ Path ของไฟล์ในเครื่องเรานะครับ - การทำ Async ก่อนอื่น ปกติการทำงานของ Script จะเป็นแบบบนลงล่างนะครับ ซึ่งงานในบรรทัดบนจะต้องทำเสร็จก่อนถึงจะทำงานในบรรทัดล่างต่อไล่ลงมาเรื่อย อันนี้เรียกว่า Sync (Synchronous) แต่เนื่องจากบางงานเราไม่จำเป็นต้องรองานอื่นเสร็จก่อน แต่เริ่มทำพร้อมกันได้เลย อันนี้ก็จะเรียก Async นะครับ ซึงแบ่งได้สองแบบนะครับ
- แบบแรก คือสั่งงานแยกออกไปทำงานเป็นพื้นหลัง แล้วข้ามไปทำงานต่อไปเลย ทดลองด้วยการสร้าง Script ขึ้นมาอันนึง แล้วใส่โค้ดตามนี้
#!/bin/bash
echo "run"
sleep 5 &
sleep 25 &
sleep 125 &
echo "finish"
ซึ่งตัวที่ทำหน้าที่บอกว่าให้ทำงานแบบ Async นั้นคือ & นั้นเอง เอาละเซฟเป็นไฟล์ชื่อ TestAsync.sh ในโฟลเดอร์ home ของเรานะครับ แล้วคลิ๊กขวาตรงที่ว่างเลือก "Open in Terminal" ขึ้นมา แล้วพิมพ์ให้มันรัน Script ของเราด้วยคำสั่ง sh TestAsync.sh นะครับ จะเห็นผลลัพธ์ได้ว่า finish ออกมาได้ทันทีโดยไม่ต้องรอ ซึ่งในกรณีนี้งานที่เราสั่งเป็นพื้นหลังจะเสร็จตอนไหนก็ไม่ทราบนะครับ แต่ถ้ากรณีต้องการใช้ข้อมูลต่อจากงานพื้นหลังอีกที เราต้องรอให้งานพื้นหลังทำงานจนเสร็จ แล้วค่อยรันงานต่อไปนะครับ ซึ่งจะรู้ได้จากการใช้คำสั่ง wait ไว้ข้างใต้อีกทีนะครับ เช่นถ้าเราใส่ wait ไว้ใต้ sleep 125 & เราก็ต้องรอ 125 วิ ก่อนถึงจะ echo "finish" นะครับ
- แบบที่สอง เป็นการทำงานแบบ parallel ให้ติดตั้งด้วยคำสั่งนี้ก่อน
sudo apt install parallel เมื่อเขียนคำสั่งให้ตามด้วย
| parallel ก่อนทำคำสั่งอื่นๆ เช่น
ls | parallel -j 10 gzip
ls | parallel -j 10 gunzip
ซึ่งการทำงานในคำสั่งบนคือ ทำการ zip ไฟล์ใน /home/ NameUser ของเราทีละ 10 ไฟล์นะครับ ส่วนคำสั่งล่างก็คือคลายบีบอัดไฟล์ของเราทีละ 10 ไฟล์เช่นกัน นอกจากนี้ยังมีคำสั่งประเภท clustershell ที่เอาไว้ใช้สั่งงานกระจายไปหลายเซิฟเวอร์ได้ด้วยนะครับ ซึ่งยังไม่ขอกล่าว เพราะหาเซิฟเวอร์ลองเทสไม่ได้ 555
- แบบแรก คือสั่งงานแยกออกไปทำงานเป็นพื้นหลัง แล้วข้ามไปทำงานต่อไปเลย ทดลองด้วยการสร้าง Script ขึ้นมาอันนึง แล้วใส่โค้ดตามนี้
- เนื่องมาจากข้อที่ 6. นะครับ เมื่อใช้ & ทำงานเป็นพื้นหลัง เวลาเราต้องการที่หยุดการทำงานของมันก็ต้องหามันก่อนนะครับ ด้วยคำสั่ง ps -aux | grep NameFile.sh แล้วกำจัดมันทิ้งด้วยคำสั่ง sudo kill -9 pid ของพอร์ตไฟล์ที่เราต้องการกำจัดนะครับ
- sudo apt install xdotool อันนี้เอาไว้ใช้คำสั่งทนการกด keyboard นะครับ สามารถใช้ร่วมกับ script ได้ด้วยคำสั่ง xdotool key ctrl+l โดยที่ ctrl+l เป็นคำสั่งเคลียร์หน้าจอนะครับ
- time คำสั่งนี้เอาไว้หน้าคำสั่งอื่นๆ ได้นะครับ ใช้เพื่อจับเวลาการทำงานของคำสั่งอื่นๆ ที่ตามหลังในบรรทัดเดียวกัน
- การส่งข้ามตัวแปรจาก Bash Script ไปให้ Python Script นะครับ
- แบบแรกสามารถทำได้ด้วยคำสั่ง
GetDataFromPython=`python
File
Name
.py
$var1 $var2 $var3
... `
ส่วนการรับตัวแปรในส่วนของ python ทำได้ด้วยการ
import sys และคำสั่ง
GetDataFromBash=
str(sys.argv[
1:])
โดยข้อมูลที่ได้มาจะอยู่ในรูปแบบ list ของ string นะครับ ตำแหน่งที่ 0 ของ list จะเป็นชื่อไฟล์ของ
File
Name
.py
นะครับ ดังนั้นข้อมูลตัวแปรจะเริ่มที่ตำแหน่งที่ 1 (
[
1:]
คือตัวแรกจนตัวสุดท้าย)แล้วก็อย่าลืมแปลง type ตัวแปรด้วยนะครับ ตัวอย่าง
คำสั่งใน Bash Script ชื่อไฟล์แล้วแต่จะตั้ง
#!/bin/bash
sendData="Test"
GetDataFromPython=`python PassToPy.py $sendData`
echo " $GetDataFromPython"
คำสั่ง Python Script ในไฟล์ PassToPy.py
#!/usr/bin/env python3
import sys
GetDataFromBash = str(sys.argv[ 1])
GetDataFromBash = GetDataFromBash + "PassData"
print GetDataFromBash
เมื่อใช้ sh เรียกชื่อไฟล์ Bash Script ของเราจะได้ TestPassData กลับมานะครับ ซึ่งแสดงว่ามันส่งผ่านเข้าใน Python Script กลับมาแล้วนะครับ *หมายเหตุ ข้อมูลในตัวแปรที่จะส่งไปต้องไม่มีเว้นวรรคนะครับ ถ้ามีจะถูกตัดออกเป็นอีกตัวแปรใน list เช่น ถ้า sendData="Test Bash Script" ข้อที่ Python Script ได้รับจะเป็น list ของ ['Test', 'Bash', 'Script'] แทนนะครับ กรณีที่แย่แต่ใช้ได้จริงอีกกรณีคือ ใช้ Text File แทน Database ครับ 555 - แบบที่สองส่งออกตามชื่อตัวแปรด้วยคำสั่ง export นะครับ ตัวอย่าง
คำสั่งใน Bash Script ชื่อตามแต่จะตั้งอีกเช่นเดิม
#!/bin/bash
sendData1="Test"
sendData2=3
export sendData1 sendData2
python ExportToPy.py
คำสั่ง Python Script ในไฟล์ชื่อ ExportToPy.py
#!/usr/bin/env python3
import os
var1=os.environ["sendData1"]
var2=os.environ["sendData2"]
print var1+var2
เมื่อใช้ sh เรียกชื่อไฟล์ Bash Script ของเราจะได้ผลลัพธ์ Test3 นะครับ
- แบบแรกสามารถทำได้ด้วยคำสั่ง
GetDataFromPython=`python
File
Name
.py
$var1 $var2 $var3
... `
ส่วนการรับตัวแปรในส่วนของ python ทำได้ด้วยการ
import sys และคำสั่ง
GetDataFromBash=
str(sys.argv[
1:])
โดยข้อมูลที่ได้มาจะอยู่ในรูปแบบ list ของ string นะครับ ตำแหน่งที่ 0 ของ list จะเป็นชื่อไฟล์ของ
File
Name
.py
นะครับ ดังนั้นข้อมูลตัวแปรจะเริ่มที่ตำแหน่งที่ 1 (
[
1:]
คือตัวแรกจนตัวสุดท้าย)แล้วก็อย่าลืมแปลง type ตัวแปรด้วยนะครับ ตัวอย่าง
- กรณีที่อยากให้รัน bash script ทุกครั้งหลังรีสตาร์ทเครื่องนะครับ ให้เอาไฟล์ไปใส่ไว้ใน /etc/profile.d/ นะครับ
- กรณีที่ bash script ต้องการสิทธิ์ sudo เราสามารถที่จะข้ามขั้นตอนการขอสิทธิ์ได้ด้วยคำสั่ง sudo visudo เพื่ออนุญาตสิทธิ์ให้เราเพิ่มคำสั่งล่างสุด USERNAME ALL=(ALL:ALL) NOPASSWD:/usr/bin/SERVICE เข้าไปนะครับ โดย USERNAME คือชื่อ user ที่มีสิทธิ์ sudo นะครับ และก็ SERVICE คือชื่อของ service ที่เราต้องการให้ข้ามการเรียกใช้ sudo ครับ (ในส่วนนี้มันมีวิธีรันให้มันรีเควส password จากเราก็ได้นะครับ)
ความคิดเห็น
แสดงความคิดเห็น