การเริ่มต้นสคริปต์เป็นผู้ใช้อื่น


12

ฉันได้สร้างสคริปต์ใน /etc/init.d/ ซึ่งจะต้องเรียกใช้สคริปต์อื่น ๆ จากผู้ใช้ (ไม่ใช่ผู้ใช้ที่มีสิทธิ์รูท) จากโฮมไดเรกทอรีของพวกเขาราวกับว่าพวกเขาเริ่มต้นมัน

ฉันเปิดใช้งานสคริปต์เหล่านี้ด้วย: sudo -b -u <username> <script_of_a_particular_user>

และมันใช้งานได้ แต่สำหรับสคริปต์ของผู้ใช้ทุกคนที่ยังคงทำงานอยู่ (ตัวอย่างเช่นสุนัขเฝ้าบ้านบางคน) ฉันเห็นกระบวนการ sudo หลักที่เกี่ยวข้องยังมีชีวิตอยู่และทำงานเป็นรูท สิ่งนี้สร้างความยุ่งเหยิงในรายการกระบวนการที่ใช้งานอยู่

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

คำอธิบายโดยละเอียดเพิ่มเติม:
โดยทั่วไปฉันพยายามให้ผู้ใช้รายอื่นบนเครื่องมีวิธีการรันสิ่งต่าง ๆ เมื่อระบบเริ่มต้นหรือปิดระบบโดยการเรียกใช้ไฟล์ปฏิบัติการที่พบในไดเรกทอรีย่อยตามลำดับที่พบในไดเรกทอรีบ้านของพวกเขา เนื่องจากฉันไม่พบวิธีอื่นใดที่ฉันเขียนสคริปต์ทุบตีของฉันที่ทำอย่างนั้นและฉันได้กำหนดค่าเป็นสคริปต์บริการ (โดยทำตามตัวอย่างโครงกระดูก) ใน /etc/init.d/ ดังนั้นเมื่อมันทำงาน ด้วยอาร์กิวเมนต์เริ่มต้นมันจะเปิดตัวทุกอย่างจากไดเรกทอรีเริ่มต้นขึ้นและเมื่อมันถูกเรียกใช้ด้วยอาร์กิวเมนต์หยุดมันจะเปิดตัวทุกอย่างจากไดเรกทอรี. shutDown ของผู้ใช้ทั้งหมดเช่นเดียวกับพวกเขา

หรือฉันก็สนใจถ้าฉันสามารถใช้วิธีแก้ปัญหาที่มีอยู่เพื่อแก้ปัญหานี้ได้

อัปเดต
ฉันดูรอบ ๆ แล้วฉันพบคำถามนี้: /unix/22478/detach-a-daemon-using-sudo

คำตอบที่ยอมรับได้มีการใช้: ใช้sudo -u user sh -c "daemon & disown %1"งานได้สำหรับฉันที่จะ แต่ฉันก็ลองโดยไม่ปฏิเสธ% 1และมันก็เหมือนกัน ดังนั้นนี่คือสิ่งที่เหมาะกับฉันตามที่คาดไว้:

sudo -u <username> bash -c "<script_of_a_particular_user> &"

คำถามเพิ่มเติมของฉันตอนนี้คือทำไมมันทำงานโดยไม่ปฏิเสธ? ฉันควรจะยังคงสายที่ปฏิเสธไม่ว่าจะเป็นกรณีพิเศษที่เป็นไปได้หรือไม่

อัพเดท 2

เห็นได้ชัดว่ามันใช้งานได้เช่นกัน:

su <username> -c "<script_of_a_particular_user> &"

มีความแตกต่างระหว่างการโทรนี้และการโทร sudo หรือไม่? ฉันรู้ว่านี่อาจเป็นคำถามที่แตกต่างทั้งหมด แต่เนื่องจากฉันกำลังค้นหาคำตอบที่นี่ตัวเองอาจจะเพื่อประโยชน์ของหัวข้อนี้ใครบางคนสามารถชี้แจงได้ที่นี่

อัปเดต 3
ทั้งสองวิธีด้วย su หรือ sudo ตอนนี้สร้างกระบวนการstartparใหม่(กระบวนการเดียวที่ทำงานเป็นรูท) หลังจากที่ฉันบูทเครื่อง มองเห็นได้ในรายการกระบวนการเป็น:

startpar -f -- <name_of_my_init.d_script>

ทำไมกระบวนการนี้ถึงเกิดขึ้น เห็นได้ชัดว่าฉันกำลังทำอะไรผิดเนื่องจากไม่มีสคริปต์ init.d อื่นที่กำลังทำงานอยู่

ปรับปรุง 4
ปัญหาเกี่ยวกับ startpar ได้รับการแก้ไข ฉันได้เริ่มต้นคำถามอื่นแล้ว:
กระบวนการ startpar หยุดทำงานเมื่อเริ่มกระบวนการจาก rc.local หรือ init.d

และคำถามอื่นเพื่อหารือเกี่ยวกับกลไกการเปิดตัวสำหรับผู้ใช้ที่ไม่มีสิทธิพิเศษเพิ่มเติม:
ให้ผู้ใช้ปกติ (ที่ไม่ใช่รูท) ด้วยการเริ่มต้นและปิดการทำงานอัตโนมัติ

คำตอบ:


18

คำตอบที่ถูกต้องสำหรับสิ่งนี้คือ "daemonization" ที่เหมาะสมอินพุตมาตรฐานเอาต์พุตมาตรฐานและข้อผิดพลาดมาตรฐานต้องถูกเปลี่ยนเส้นทางไปยัง / dev / null (หรือไฟล์จริงบางไฟล์):

su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"

su - แทนข้อมูลประจำตัวผู้ใช้ให้กับsomeuser
-c - su เพื่อเรียกใช้คำสั่ง
nohup ที่ระบุ- เรียกใช้คำสั่งยกเว้นเพื่อแฮงค์ เพื่อป้องกันกรณีที่กระบวนการหลักจะยุติกระบวนการลูก เพิ่มที่นี่ในกรณี แต่จริงๆแล้วไม่มีผลในกรณีของฉันโดยเฉพาะ ไม่ว่าจะเป็นสิ่งที่จำเป็นขึ้นอยู่กับสภาพแวดล้อม (ตรวจสอบshopt )
> / dev / null - เปลี่ยนเส้นทางเอาต์พุตมาตรฐานเป็นไม่มีอะไรโดยทั่วไปจะปิดใช้งาน
2> & 1 - ข้อผิดพลาดมาตรฐานเปลี่ยนเส้นทาง (2) เอาต์พุตไปยังเอาต์พุตมาตรฐาน (1) ซึ่งถูกเปลี่ยนเส้นทางไปเป็นโมฆะ
& - แยกออกเป็นพื้นหลังสิ่งนี้จะเปลี่ยนเส้นทางอินพุตมาตรฐานไปยัง / dev / null

นี่คือสิ่งที่ยูทิลิตี้start-stop-daemonจาก Debian dpkg ทำหน้าที่เป็นแกนหลัก นั่นคือเหตุผลที่ฉันต้องการเริ่มต้นสคริปต์ด้วยวิธีนี้แทนที่จะแนะนำการเรียกโปรแกรมอรรถประโยชน์ภายนอกอื่นในรหัสของฉัน start-stop-daemonมีประโยชน์ในกรณีที่คุณมีโปรแกรม blown daemon เต็มรูปแบบที่คุณต้องการเริ่มต้นและที่ที่คุณต้องการฟังก์ชั่นเพิ่มเติมที่start-stop-daemon จัดเตรียมไว้ (ตัวอย่างเช่นการตรวจสอบว่ากระบวนการที่ระบุทำงานอยู่หรือไม่ จะไม่เปิดอีกครั้ง)

นอกจากนี้ยังเป็นที่น่าสังเกตว่าคุณสามารถปิดตัวอธิบายไฟล์ของกระบวนการแทนการเปลี่ยนเส้นทางไปยัง/ dev / nullตัวอย่างเช่น:

su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"

0 <& -ปิดอินพุตมาตรฐาน (0)
1> & -ปิดเอาต์พุตมาตรฐาน (1)
2> & -ปิดข้อผิดพลาดมาตรฐาน (2) เอาต์พุต

ทิศทางของเครื่องหมาย <> ไม่สำคัญว่าจะระบุหมายเลขตัวอธิบายไฟล์แบบยาว ดังนั้นนี่คือสิ่งที่ดีเท่าเทียมกัน:

su someuser -c "some_script.sh 0>&- 1>&- 2>&- &"

หรือ

su someuser -c "some_script.sh 0<&- 1<&- 2<&- &"

อย่างไรก็ตามมีวิธีที่สั้นกว่าเล็กน้อยในการเขียนโดยไม่มีตัวเลขสำหรับ stdin และ stdout โดยที่ทิศทางมีความสำคัญ:

su someuser -c "some_script.sh <&- >&- 2>&- &" 

เมื่อตัวให้คำอธิบายไฟล์ถูกปิดหรือเปลี่ยนเส้นทางไปยัง / dev / null ( start-stop-daemonกำลังทำการเปลี่ยนทิศทางไปยัง / dev / null) กระบวนการจะปลอดภัยที่จะทำงานในพื้นหลังเป็น daemon ดังนั้นนี่คือสิ่งที่จำเป็นเพื่อหลีกเลี่ยงปัญหา ( startpar ) ด้วยการเรียกใช้สคริปต์ในช่วงเวลาบูต

ฉันใช้งานโซลูชันทั้งหมดจากแนวคิดเริ่มต้นของฉันและวางไว้บน GitHub:
https://github.com/ivankovacevic/userspaceServices


Ivan จะดีกว่าถ้าใช้ su หรือ su -login? ฉันอ่านคนซู แต่ฉันไม่สามารถเข้าใจในกรณีนี้โดยเฉพาะ
Massimo

1
@ Massimo ขอโทษสำหรับความล่าช้าในการตอบสนองของฉัน! ตรวจสอบคำถามนี้: unix.stackexchange.com/questions/318572/…มีหน้าคู่มือที่ดีกว่าที่อธิบายไว้ ความแตกต่างโดยทั่วไปคือการตั้งค่าไดเรกทอรีการทำงานและตัวแปรสภาพแวดล้อม ฉันจะบอกว่าสำหรับกรณีการใช้งานเช่นนี้ (ทำบางสิ่งในฐานะผู้ใช้รายอื่น) อาจเป็นตัวเลือกที่ดีกว่าที่จะใช้ -login จริง ๆ
Ivan Kovacevic

3

คุณสามารถใช้start-stop-daemon out of init.d พร้อม--userตัวเลือก


ฉันได้แสดงความคิดเห็นเกี่ยวกับ start-stop-daemon จากคำตอบของ Mr Shark และฉันก็ทำการอัปเดตสำหรับคำตอบและคำถามของฉัน (อัปเดต 4)
Ivan Kovacevic

2

ฉันยังไม่ได้ทดสอบอย่างเต็มที่ แต่ฉันคิดว่ามีลักษณะเช่นนี้:

/sbin/start-stop-daemon --background --start --exec /home/USER/.startUp --user USER --pidfile=/home/USER/.startUp.pid --make-pidfile

เมื่อเริ่มต้นแล้ว

/sbin/start-stop-daemon --stop --user USER --pidfile=/home/USER/.startUp.pid

เมื่อปิดตัวลง

การจัดการสคริปต์. shutDown สามารถทำได้โดยบางอย่างเช่นสิ่งที่เริ่มต้น แต่คุณไม่สามารถแน่ใจได้ว่าสคริปต์จะทำงานจนจบตั้งแต่การปิดระบบควรเกิดขึ้นต่อไป :-)

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


2
เป็นหลักนี้จะทำงาน! start-stop-daemon สามารถเรียกใช้กระบวนการได้สำเร็จตอนบูทหรืออย่างอื่น ฉันได้ทำการทดสอบแล้ว และมันก็กำจัดปัญหานั้นด้วยกระบวนการห้อย startpar อย่างไรก็ตามคุณยังขาด - ผู้ใช้ปลายทางในการโทรเริ่มต้นของคุณ หากไม่มีมันก็จะเปิดกระบวนการเป็นรูต ไฟล์ pid ควรถูกเขียนไปยัง / var / run / เนื่องจากไม่เช่นนั้นจะสร้างไฟล์ที่เป็นเจ้าของรูทในโฮมไดเร็กทอรีของผู้ใช้ แต่ในความคิดของฉันสำหรับสคริปต์ทั่วไปที่เรียกใช้ start-stop-daemon ดูเหมือนว่าจะมีค่าใช้จ่ายมากเกินไป ตรวจสอบคำตอบของฉันที่ฉันพยายามอธิบายเหตุผล
Ivan Kovacevic

1

คุณเคยลองใช้suไหม?

su -c /home/user/.startUp/executable - user

-c บอกให้ su ดำเนินการคำสั่งและพารามิเตอร์สุดท้ายคือผู้ใช้เรียกใช้งานมัน


ใช่มันใช้งานได้ แต่มีใบเสนอราคาและเพิ่มเครื่องหมายและ และฉันคิดว่ามันสะอาดกว่าที่จะเขียนเหมือน: su <username> -c "/some/path/script.sh &" โดยทั่วไปฉันใช้ sudo เพราะดูเหมือนว่าจะสะอาดกว่า แต่ตอนนี้มันใช้แล้วดีกว่า: sudo - u <username> bash -c "/some/path/script.sh &" ไม่ทราบว่ามีความแตกต่างในสองสิ่งนั้นหรือไม่
Ivan Kovacevic
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.