msgbartop
Just another blog of mine
msgbarbottom

08 Jul 08 expect

ขอพูดถึงคำสั่ง unix ต่ออีกอันหนึ่งละกัน เนื่องจากเมื่อวานพยายามเขียน script เพื่อสร้าง account แบบเยอะๆ โดยใช้ข้อมูลในไฟล์รายชื่อนักเรียน เพราะว่ามีนักเรียนอยู่ 120 กว่าคน ถ้าให้สร้างด้วยมืออาจจะหมดแรงก่อนได้ ปัญหาเกิดขึ้นตอนกำหนด password ที่แม้ว่าจะมีโปรแกรม pwgen สำหรับสร้าง password ให้โดยอัตโนมัติแล้วก็ตาม แต่โปรแกรม adduser ที่ใช้บน Ubuntu ไม่ยอมให้กำหนด password ไว้เป็น option จึงต้องหาวิธีอื่นๆ ซึ่งก็มีหลายวิธี เช่น เปลี่ยนไปใช้ useradd (ชื่อคล้ายกัน สับสนดีแท้) แทนเนื่องจากกำหนดรายละเอียดต่างๆ ได้เยอะ แต่ก็มีปัญหาที่จะต้องตามไปกำหนดเงื่อนไขต่างๆ ยุ่งยากพอสมควรในขณะที่ adduser มีอีกคนกำหนดค่าต่างๆ ไว้ให้แล้ว อีกวิธีหนึ่งก็จะต้องไปแก้ไฟล์ shadow เพื่อแก้ข้อมูลเอาเอง ซึ่งไม่อยากทำเท่าไหร่ กลัวผิดแล้วมีปัญหา

สุดท้ายมีคนแถวนี้แนะนำให้ใช้โปรแกรม expect ซึ่งสามารถจำลองการทำงานของโปรแกรมที่ต้องมีการตอบโต้กับผู้ใช้ ให้เราสามารถส่งค่าได้เหมือนกับสั่งงาน โดย expect นี้จะใช้ regular expression เพื่อเทียบข้อความที่โปรแกรมแสดงออกมา แล้วจึงสามารถใช้คำสั่ง send เพื่อส่งข้อความหรืออินพุตกลับไปได้ เช่น

#!/usr/bin/expect -f
 
spawn passwd [lindex $argv 0]
set password [lindex $argv 1]
expect "password:"
send "$password\r"
expect "password:"
send "$password\r"
expect eof

จากโปรแกรม คำสั่ง expect เป็นการกำหนดให้รอจนกระทั่งมีข้อความที่กำหนดแสดงขึ้นมา ส่วนคำสั่ง send ก็จะเป็นส่งข้อมูลซึ่งก็คือ password ของเราไปให้โปรแกรม ที่เรียกมาทำงานโดยใช้คำสั่ง spawn ทั้งหมดนี้ไม่ได้เขียนเองหรอก ดูจากที่อ้างอิงได้

อ้างอิง: http://floppsie.comp.glam.ac.uk/Glamorgan/gaius/scripting/5.html

Tags: ,

05 Jul 08 AWK

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

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

4822111111	10
4822222222	13
4833333333	14
4844444444	9

ถ้าจะแปลงข้อมูลในไฟล์นี้เป็นตารางในแบบ html ก็ทำได้โดยอ่านไฟล์มาทีละบรรทัด แล้วเพิ่มแท็ก tr และ td ลงไป

BEGIN {
  FS="\t"
  print "<table>"
}
 
{
  print "<tr><td>"$1"</td><td>"$2"</td></tr>"
}
 
END {
  print "</table>"
}

เมื่อเขียนเสร็จ ก็ลองเอามาใช้งานได้โดย

$ awk -f [awk-file] &lt; [data-file]

จะได้ผลเป็นตารางในตามข้างล่าง

<table border="0">
<tr>
<td>4822111111</td>
<td>10</td>
</tr>
<tr>
<td>4822222222</td>
<td>13</td>
</tr>
<tr>
<td>4833333333</td>
<td>14</td>
</tr>
<tr>
<td>4844444444</td>
<td>9</td>
</tr>
</table>

ในโปรแกรม awk ข้างต้น แบ่งออกเป็น 3 ส่วน แต่ละส่วนแบ่งด้วยวงเล็บปีกกา ส่วนแรกมีคำว่า BEGIN กำหนดอยู่หมายความว่าให้ทำครั้งเดียวตอนเริ่มต้นอ่านไฟล์ ในที่นี้กำหนดให้ใช้แท็บเป็นตัวแบ่งฟิลด์ แล้วก็พิมพ์ “<table>” ออกมา

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

ส่วนที่สามเริ่มต้นด้วย END จะทำงานเพียงครั้งเดียวเมื่ออ่านไฟล์ทั้งหมดเสร็จแล้ว ดังนั้นจึงแค่พิมพ์ “</table>” ออกมาในตอนท้าย

ด้วยลักษณะที่ awk ทำงานตามเรคอร์ดและฟิลด์ ทำให้การเขียนโปรแกรมเพื่อจัดการกับข้อมูลต่างๆ ทำได้สะดวกขึ้น ไม่จำเป็นต้องเขียนลูปเพื่อวนรอบ แค่เขียนเป็นกฎไว้เท่านั้นก็พอ นอกจากนี้ยังสามารถระบุให้ทำงานกับเรคอร์ดที่แตกต่างกันได้ด้วย โดยใช้ Regular Expression กำหนดรูปแบบของเรคอร์ดนั้น เช่น

/^4822/ { print "48" }

กฎข้างต้นจะทำให้พิมพ์คำว่า “48″ เมื่อเรคอร์ดขึ้นต้นด้วย “4822″ ตามที่กำหนดไว้ใน RE เท่านั้น

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

แต่ว่าโปรแกรมข้างต้นก็ยังมีข้อจำกัดอยู่ที่กำหนดจำนวนฟิลด์ไว้ตายตัว ทำให้ไม่ยืดหยุ่นเท่าไหร่ ถ้ามีคะแนนหลายๆ ค่า แต่เนื่องจาก awk นั้นมี control structure อยู่หลายแบบ จึงสามารถเขียนให้ยืดหยุ่นขึ้นได้อีกเป็น

BEGIN {
  FS=" "
  ORS=""
  print "<table class=\"attendance\" border=\"0\">\n"
}
 
{
  print "<tr>"
  for(i=1; i&lt;=NF; i++)
    print "<td>"$i"</td>"
  print "</tr>\n"
}
 
END {
  print "</table>\n"
}

NF เป็นตัวแปรระบุจำนวนฟิลด์ ซึ่งทำให้เราสามารถใช้ลูปเพื่อพิมพ์ข้อมูลจากทุกๆ ฟิลด์ได้

Tags: , , ,

25 May 07 mcrypt

mcrypt เป็นโปรแกรมที่พํฒนาขึ้นเพื่อทดแทน crypt บน Unix ซึ่งใช้สำหรับเข้ารหัสไฟล์ข้อมูล พอดีตอนนี้ต้องสำรองข้อมูลจาก mysql ไปไว้ที่อื่น เลยอยากเข้ารหัสด้วย เพื่อเพิ่มความปลอดภัย ก็เลยเขียน shell script ขึ้นมาอันนึง ให้เรียก mysqldump จากนั้นก็เรียก mcrypt มาเข้ารหัส แล้วค่อยส่งไปเก็บไว้ที่อีกเครื่องหนึ่ง

วิธีใช้ mcrypt ก็ไม่ยาก เพียงแค่กำหนดขั้นตอนวิธีที่จะใช้เข้ารหัส รวมทั้งวิธีระบุกุญแจที่จะใช้ เช่น

mcrypt -a des --keymode pkdes [filename]

โปรแกรมก็จะรอให้กำหนดกุญแจที่จะใช้ ถ้ากำหนดเรียบร้อยแล้ว ก็จะเข้ารหัสให้ และได้ไฟล์ใหม่โดยเติม .nc เข้าไปข้างท้าย วิธีนี้จะใช้สำหรับ interactive เท่านั้น ถ้าเป็นกรณีที่ต้องการใช้ใน shell script ก็ต้องกำหนดให้ไปเอากุญแจมาจากไฟล์ เช่น

mcrypt -a des --keymode pkdes -f [key-file] [filename]

แต่ปัญหาที่พบก็คือขั้นตอนวิธีเข้ารหัส แต่ละอันจะมีข้อกำหนดเรื่องความยาวสูงสุดของกุญแจ ถ้ากำหนดยาวเกินไปก็จะเกิด error ขึ้น เช่น DES จะรองรับแค่ 8 ตัวอักษรเท่านั้น จึงต้องดูเรื่องนี้ประกอบด้วย โดยรายละเอียดจะมีอยู่ที่ –list-keymodes

Tags: