ผมไม่คิดว่านี่คือทั้งหมดเป็นปัญหาทุบตี
ในความคิดเห็นคุณบอกว่าคุณเห็นข้อผิดพลาดนี้หลังจากทำ
sudo su username2
username
เมื่อเข้าสู่ระบบเป็น มันคือสิ่งsu
ที่ก่อให้เกิดปัญหา
/dev/stdout
เป็น symlink ไป/proc/self/fd/1
ซึ่งเป็น symlink /dev/pts/1
ไปสำหรับตัวอย่างเช่น /dev/pts/1
ซึ่งเป็น pseudoterminal เป็นเจ้าของและเขียนได้โดย, username
; ความเป็นเจ้าของนั้นได้รับเมื่อusername
เข้าสู่ระบบเมื่อคุณsudo su username2
ความเป็นเจ้าของ/dev/pts/1
จะไม่เปลี่ยนแปลงและusername2
ไม่มีสิทธิ์ในการเขียน
ฉันขอยืนยันว่านี่เป็นข้อผิดพลาด /dev/stdout
ควรเป็นนามแฝงสำหรับเอาต์พุตสตรีมมาตรฐาน แต่ที่นี่เราเห็นสถานการณ์ที่ใช้echo hello
งานได้ แต่echo hello > /dev/stdout
ล้มเหลว
วิธีแก้ปัญหาหนึ่งคือการทำให้username2
สมาชิกของกลุ่มtty
แต่ที่จะให้username2
สิทธิ์ในการเขียนถึงtty ใด ๆซึ่งอาจไม่พึงประสงค์
วิธีแก้ปัญหาอีกก็จะไปเข้าสู่ระบบไปยังusername2
บัญชีแทนที่จะใช้su
เพื่อให้/dev/stdout
ชี้ไปยัง pseudoterminal username2
จัดสรรใหม่เป็นเจ้าของโดย สิ่งนี้อาจไม่สามารถใช้งานได้จริง
วิธีแก้ปัญหาอื่นคือแก้ไขสคริปต์ของคุณเพื่อไม่ให้อ้างอิง/dev/stdout
และ/dev/stderr
; ตัวอย่างเช่นแทนที่สิ่งนี้:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
โดยสิ่งนี้:
echo OUT
echo ERR 1>&2
ฉันเห็นสิ่งนี้ในระบบของฉันเอง Ubuntu 12.04 กับ bash 4.2.24 - แม้ว่าเอกสาร bash ( info bash
) ในระบบของฉันจะบอกว่า/dev/stdout
และ/dev/stderr
ได้รับการดูแลเป็นพิเศษเมื่อใช้ในการเปลี่ยนเส้นทาง แต่แม้ว่า bash จะไม่ปฏิบัติต่อชื่อเหล่านั้นเป็นพิเศษ แต่ก็ควรทำหน้าที่เทียบเท่ากับสตรีม I / O มาตรฐาน (POSIX ไม่ได้กล่าวถึง/dev/std{in,out,err}
ดังนั้นอาจเป็นการยากที่จะโต้แย้งว่านี่เป็นข้อบกพร่อง)
เมื่อดูที่ทุบตีรุ่นเก่าเอกสารแสดงนัยว่า/dev/stdout
et al ได้รับการดูแลเป็นพิเศษไม่ว่าจะมีไฟล์อยู่หรือไม่ก็ตาม คุณลักษณะถูกนำมาใช้ใน bash 2.04 และNEWS
ไฟล์สำหรับรุ่นนั้นบอกว่า:
รหัสการเปลี่ยนเส้นทางตอนนี้จัดการชื่อไฟล์หลายชื่อเป็นพิเศษ: / dev / fd / N, / dev / stdin, / dev / stdout และ / dev / stderr ไม่ว่าจะมีอยู่ในระบบไฟล์หรือไม่
แต่ถ้าคุณตรวจสอบซอร์สโค้ด ( redir.c
) คุณจะเห็นว่ามีการเปิดใช้การจัดการพิเศษเฉพาะเมื่อHAVE_DEV_STDIN
มีการกำหนดสัญลักษณ์(ซึ่งจะถูกกำหนดเมื่อ bash ถูกสร้างจากซอร์ส)
เท่าที่ฉันสามารถบอกได้ว่าไม่มีการทุบตีรุ่นที่ปล่อยออกมาเป็นการจัดการแบบพิเศษของ/dev/stdout
et al โดยไม่มีเงื่อนไข - เว้นแต่การแจกจ่ายบางอย่างได้ทำการแก้ไขแล้ว
ดังนั้นวิธีแก้ปัญหาอื่น (ซึ่งฉันไม่ได้ลอง) ก็คือการคว้าแหล่งทุบตีแก้ไขredir.c
เพื่อให้การ/dev/*
จัดการพิเศษโดยไม่มีเงื่อนไขและใช้เวอร์ชันที่สร้างใหม่ของคุณแทนที่จะเป็นรุ่นที่มาพร้อมกับระบบของคุณ นี่อาจจะเกินความจริงได้
สรุป :
ระบบปฏิบัติการของคุณเช่นเหมืองไม่ได้จัดการกรรมสิทธิ์และสิทธิ์ของ/dev/stdout
และ/dev/stderr
ถูกต้อง ทุบตีควรปฏิบัติต่อชื่อเหล่านี้เป็นพิเศษในการเปลี่ยนเส้นทาง แต่ในความเป็นจริงมันจะทำเช่นนั้นเฉพาะในกรณีที่ไม่มีไฟล์ ที่จะไม่สำคัญว่า/dev/stdout
และ/dev/stderr
ทำงานอย่างถูกต้อง ปัญหานี้จะปรากฏขึ้นเมื่อคุณsu
ไปยังบัญชีอื่นหรือทำสิ่งที่คล้ายกัน หากคุณเพียงแค่ลงชื่อเข้าใช้บัญชีการอนุญาตนั้นถูกต้อง
ls -l /dev/stdout /dev/stderr
และls -lL /dev/stdout /dev/stderr
?