บันทึกผลลัพธ์ของพื้นหลังหรือสคริปต์บูต


10

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

ฉันจะรู้ได้อย่างไรว่าเกิดอะไรขึ้น สคริปต์นั้นเป็นชุดคำสั่งดังนี้:

/bin/foo on 3
sudo bar a

ฉันเข้าใจว่านี่เป็นจุดประสงค์ในการสอนเกี่ยวกับการดีบักสคริปต์ของระบบ แต่ก็เป็นบิตเช่นU&Lกัน ฉันอ่านชื่อเรื่องผิดและขอแนะนำ "การบันทึกผลลัพธ์ของสคริปต์ระบบสำหรับการดีบัก" จะทำให้วัตถุประสงค์ชัดเจนขึ้น สมองของฉันค้างเมื่อฉันอ่านfoo barตัวอย่างเหล่านี้ฉันชอบสิ่งที่ดูโลกแห่งความจริงมากขึ้น ฉันลังเลที่จะแก้ไขโพสต์ใด ๆ ดังนั้นจะปล่อยให้คุณถ้าคุณคิดว่ามันจะดีขึ้น
Milliways

1
@Milliways คุณพูดถูก "สคริปต์ระบบ" เป็นชื่อเรียกที่ผิดดังนั้นฉันจึงได้เปลี่ยนชื่อ ฉันไม่เห็นด้วยกับสิ่งที่ foobar - ผู้คนจำเป็นต้องเรียนรู้ที่จะรับรู้ศัพท์แสง / ภาษาที่พบบ่อยเช่นเดียวกับที่พวกเขาอาจในวัฒนธรรมใด ๆ นอกจากนี้ยังเป็นขำดีเมื่อคุณใส่ทั้งสองเข้าด้วยกัน
goldilocks

คำตอบ:


8

sudoขั้นแรกถ้าสคริปต์ที่จะดำเนินการโดยภูตของระบบและภูตที่ใช้มีสิทธิ์รากคุณไม่จำเป็นต้องใช้ ซึ่งรวมถึงinit(และsystemd) rc.localซึ่งรวมถึง หาก daemon นั้นไม่ได้ทำงานด้วยสิทธิ์พิเศษรูทsudoจะไม่ทำงานจนกว่า/etc/sudoersจะมีการกำหนดค่าให้อนุญาต (และไม่มีรหัสผ่าน) ผู้ใช้ Raspbian อาจสับสนเนื่องจากpiผู้ใช้จะได้รับอนุญาตให้ทำสิ่งใดตามค่าเริ่มต้น (และหากคุณดู/etc/sudoersคุณจะเห็นว่าสำเร็จได้อย่างไร)

ถัดไปคุณสามารถจับเอาท์พุทจากbashสคริปต์ใด ๆหรือชุดคำสั่งใด ๆ ภายในสคริปต์ทุบตีโดยดำเนินการพวกเขาใน subshell ดังนี้: 1

(
    /bin/foo on 3
    sudo bar a
) &> /var/log/myTestLog.txt

()บ่งชี้subshell เอาต์พุตทั้งหมดจากสิ่งใด ๆ ภายในสิ่งนี้จะถูกเปลี่ยนเส้นทางไปยัง/var/log/myTestLog.txtไฟล์ หมายเหตุเล็กน้อย:

  • &>เป็นbashismดังนั้นหากสคริปต์ที่จะดำเนินการผ่านทางshebangในบรรทัดแรกก็ควรจะไม่เพียง#!/bin/bash /bin/sh"Bashisms" ใช้งานได้ในbashเชลล์เท่านั้น

    ซึ่งรวมถึงการ/etc/rc.localใช้งานตามค่าเริ่มต้น/bin/sh(เช่นใช่คุณสามารถเปลี่ยนได้อย่างปลอดภัย/bin/bash)

  • /var/logต้องการสิทธิ์รูทเพื่อเขียน หากกระบวนการนี้ไม่มีให้ใช้หรือสร้างไดเรกทอรีที่คุณรู้ว่าทำได้ เมื่อมีข้อสงสัยหากคุณสามารถทดสอบสิ่งนี้ได้โดยไม่ต้องปิดระบบหรือรีบูทระบบให้ใช้/tmpซึ่งเป็นสิ่งที่โลกเขียนได้ (เช่นโดยใครก็ตาม) อย่างไรก็ตาม/tmpไม่ได้คงอยู่ตลอดบูท มันเป็นพาร์ติชั่นขนาดเล็กที่ใช้ RAM ดังนั้นอย่าเขียนกิ๊กของข้อมูลลงไป มันไม่ได้เป็น SD card ของคุณ[จริงในรุ่นปัจจุบันของ Raspbian มันเป็น แต่ไม่นับรวมกับเรื่องนี้ในทางปฏิบัติ]

  • &>myTestLog.txtจะเขียนทับอะไรใน &>>แต่หากคุณต้องการที่จะผนวกกับบันทึกที่มีอยู่ซึ่งอาจจะเป็นความคิดที่ดีสำหรับการแก้จุดบกพร่องเพื่อการใช้งาน จากนั้นคุณสามารถเพิ่มคำสั่งไปยังจุดเริ่มต้นของเชลล์ย่อยเช่นนี้:

    echo Starting $(date)

    เพื่อแยกข้อมูลจากการวิ่งแต่ละครั้ง หากคุณไม่แน่ใจว่าสิ่งนี้ทำอะไรให้ลองบนบรรทัดคำสั่ง

จุดสุดท้ายนี้เป็นตัวอย่างที่ดีของสิ่งที่คุณสามารถทำได้เกี่ยวกับคำสั่งที่ไม่ส่งออกอะไร แต่ส่วนใหญ่จะทำถ้าคุณรวมเช่น-vสำหรับ "verbose" ระวังสำหรับบางคำสั่ง-vหมายถึง "ข้อมูลรุ่นที่พิมพ์" ดูที่หน้า manสำหรับคำสั่งเพื่อให้แน่ใจว่าจะใช้งานได้อย่างไรและอย่างไร (บางคำสั่งยังใช้สวิตช์ที่ต่างไปจากเดิม-v)

ตามแบบแผนคำสั่งจะส่งคืนค่า 0 เมื่อเสร็จสมบูรณ์ นี้บางครั้งเรียกว่า "ออกจากสถานะ" และคุณไม่ปกติเห็น echo $?แต่เปลือกจะแสดงให้คุณด้วย ลอง

 ls /
 echo $?
 ls /nonexistantdir
 echo $?

คุณจะได้รับ 0 และ 2 หากคุณมองหาในหน้า man สำหรับlsภายใต้ "Exit status" คุณจะเห็นรหัสลับที่ค่อนข้างไม่เจาะจง:

2      if serious trouble (e.g., cannot access command-line argument).

ซึ่งอาจจะหรืออาจจะไม่ดีกว่าไม่มีอะไร แต่มีคุณไป

อย่างน้อยที่สุดสิ่งนี้บ่งชี้ว่าคำสั่งล้มเหลวด้วยเหตุผลบางประการ สถานะการออกยังอนุญาตให้คุณทำสิ่งนี้:

/bin/foo && sudo bar

&&ในกรณีนี้หมายถึง "ถ้าคำสั่งแรกประสบความสำเร็จ" ทะนงคำสั่งแรกใช้การประชุมกลับ 0 (ซึ่งเป็นเหตุผลที่พวกเขามักจะทำ) หาก/bin/fooไม่สามารถใช้งานไม่พบ ฯลฯsudo barจะไม่เกิดขึ้น

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


1. คุณสามารถทำการเปลี่ยนเส้นทางเอาต์พุตเดียวกันสำหรับสคริปต์ทั้งหมดจากภายในโดยใช้:

exec &> /var/log/myTestLog.txt

ที่ด้านบน (หรือที่ใดก็ได้และมันจะใช้กับทุกสิ่งที่ตามมา)


2

สิ่งสำคัญอย่างหนึ่งที่ผู้คนมักจะลืมเมื่อเรียกใช้สคริปต์เนื่องจาก daemons คือสภาพแวดล้อมของเชลล์และ$PATHโดยเฉพาะอย่างยิ่งตัวแปร ในตัวอย่างของคุณบรรทัดที่สองอาศัย$PATH: ชื่อเต็มsudoคือ/usr/bin/sudoและเชลล์ผู้ใช้ของคุณเท่านั้นที่รู้เพราะมันบอกให้ค้นหา/usr/binเมื่อมองหาไฟล์ปฏิบัติการ barเช่นเดียวกับที่เป็นจริงสำหรับ

เมื่อพิจารณาว่าsudoไม่จำเป็นเมื่อเรียกใช้สคริปต์เป็น daemons บรรทัดที่สองของคุณควรมีลักษณะดังนี้:

/path/to/bar a
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.