[บันทึกกันลืม] แก้ปัญหารัน Shell Script กับมือทุกอย่างสมบูรณ์ แต่พอใช้ cron แล้วพัง

เรา “จำกันมา” ว่า การเขียน Shell Script นั้น ทำด้วยมืออย่างไร ก็เขียนลงไปในไฟล์ แล้วเอา Shell เช่น Bash ไป Run แล้วเอาไปตั้งในไฟล์ /etc/cron.d/mycron

ปัญหาคือ

บางทีเขียนด้วยภาษา Script เช่น python, R แล้วบางที ก็อยากจะเพิ่มภาษาไทยเข้าไป

ตามสูตร ก็ต้องใช้คำสั่ง locale ตรวจสอบ

LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8

ก็จะพบว่า เป็น UTF-8 สวยงาม

เขียนใส่ข้อมูลที่ประมวลผลมา ก็จะได้เป็นภาษาไทยสวยงาม

สวัสดีชาวโลก

แต่ พอเอาไปใส่ Shell Script ผลออกมาเป็นตัวอักษรบนตัวเลข ซึ่งนั่นคือ UTF-8 HEX code

<U+0E2B><U+0E32><U+0E14><U+0E43><U+0E2B><U+0E0D><U+0E48>

เหตุของปัญหา

ก็ลองเอา คำสั่ง locale ไปใส่ใน Shell Script แล้วดูผลในไฟล์พบว่า

LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

สรุปคือ locale ตอนใช้ cron เป็น Default อย่างนี้ (พอดีทำงานบน docker ที่ base image มาจาก debian)

วิธีแก้ไขปัญหา

google สิครับ รออะไร ไปพบข้อมูลจาก https://www.logikdev.com/2010/02/02/locale-settings-for-your-cron-job/

คือ ให้ใส่

SHELL=/bin/bash
LANG=en_US.UTF-8
LANGUAGE=en
LC_CTYPE=en_US.UTF-8

ลงไปใน cron ด้วย อย่างเช่น

SHELL=/bin/bash
LANG=en_US.UTF-8
LANGUAGE=en
LC_CTYPE=en_US.UTF-8
*/3 * * * * /bin/bash /code/somescript.sh

แล้วก็อย่าลืม

/etc/init.d/cron restart

เป็นอันเรียบร้อย

หวังว่าจะมีประโยชน์ครับ