ในคำสั่ง `sudo find` ฉันจะแน่ใจได้อย่างไรว่าคำสั่ง` -exec` ถูกรันเหมือนผู้ใช้ปกติ?


10

ฉันกำลังพยายามทำให้คำสั่งต่อไปนี้ทำงานในลักษณะที่process_pathsสคริปต์ไม่ได้ทำงานภายใต้สิทธิ์ระดับสูง มีวิธีทำเช่นนี้หรือไม่?

sudo find /path/ -exec process_paths '{}' \+

ที่นี่/path/มีไฟล์บางไฟล์ที่ไม่มีสิทธิ์อ่านสำหรับผู้ใช้ปกติ สคริปต์process_pathsเพียงต้องการเส้นทาง


... -exec sudo -u user process_paths {} \+
Satō Katsura

@SatoKatsura บางครั้งสิ่งนี้ล้มเหลวด้วยsudo: unable to execute /usr/bin/perl: Argument list too long: /
pii_ke

1
ใช่ดูบันทึกเกี่ยวกับSUDO_COMMANDตัวแปรในการค้นหา . [^.] * -type f -print0 | xargs -0 sudo chmod 664; ไม่ทำงาน
Stéphane Chazelas

2
ถ้าคุณต้องการให้-execคำสั่งที่จะเรียกว่าเป็นผู้ใช้ของคุณทำไมคุณทำงานfindโดยใช้sudoในสถานที่แรก?
marcelm

2
@marcelm ฉันคิดว่าประโยคสุดท้ายของคำถามตอบคุณ
เฮ้

คำตอบ:


16

ในระบบที่รองรับ (GNU และอีกไม่กี่คน) คุณสามารถทำได้:

sudo find /path/ -print0 | xargs -r0 process_paths

xargsไม่ได้ทำงานภายใต้sudoจึงยังคงมี UIDs เดิม gids / และสภาพแวดล้อมเดิม (ในความรู้สึกที่มีขนาดใหญ่) sudoไม่ได้เป็นหนึ่งแก้ไขโดย

process_pathsstdin สิ้นสุดลงด้วยการถูกปรับเปลี่ยนแม้ว่า (ขึ้นอยู่กับxargsการดำเนินงานก็เปิดอยู่บน/dev/nullหรือหุ้นpipeจาก/sudofind

เพื่อหลีกเลี่ยงการที่ (กับ GNU xargsและเปลือกหอยเหมือนksh, zshหรือbashว่ากระบวนการสนับสนุนเปลี่ยนตัว) คุณสามารถทำ:

xargs -r0a <(sudo find /path/ -print0) process_paths

ด้วยzsh:

sudo zsh -c '
   files=(/path/**/*(D))
   USERNAME=$SUDO_USER
   autoload zargs
   zargs $files -- process_paths'

ในzshการกำหนดชื่อผู้ใช้กับ$USERNAMEตัวแปรพิเศษชุด UIDs ที่ GIDS กับที่ของผู้ใช้ที่สอดคล้องกันในฐานข้อมูลผู้ใช้เช่นsudo -u "$SUDO_USER"จะทำ

คุณสามารถทำได้:

 sudo sh -c '
   exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'

แต่เนื่องจากsudoผ่าน$SUDO_COMMANDตัวแปรสภาพแวดล้อม (ซึ่งมีการต่อกันของข้อโต้แย้งที่มีช่องว่าง) ไปprocess_pathsยังรายการของไฟล์ที่ถูกส่งผ่านสองครั้งprocess_pathsซึ่งหมายความว่าข้อ จำกัด เกี่ยวกับขนาดสูงสุดของ args + env น่าจะถึงถ้ามีขนาดใหญ่ จำนวนไฟล์

ด้วยsuการติดตั้งใช้งานส่วนใหญ่คุณควรจะสามารถ:

 sudo sh -c '
   exec find /path/ -exec su "$SUDO_USER" -c '\''
     exec "$0" "$@"'\'' process_paths {} +'

แม้ว่าจะsuไม่มีปัญหาเดียวกัน


1

คุณสามารถใช้sudo:

sudo find <directory> -exec sudo -u <normal_user> <command> {} \;

แต่ดังที่กล่าวไว้ในความคิดเห็นดูเหมือนจะล้มเหลวหาก {} ยาวเกินไปสำหรับ sudo

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