หากคุณต้องการทำงานจริงๆคุณสามารถกำหนดฟังก์ชั่นเชลล์ที่เรียกว่ารันรูทเชลล์ใหม่เมื่อรันด้วยวิธีนั้นและรันคำสั่งปกติเป็นอย่างอื่นsudo cd directorybashsudosudo
ดังที่ปรากฏในคำตอบอื่น ๆ ผู้ใช้ส่วนใหญ่จะไม่ต้องการรบกวนการทำเช่นนั้น แต่ต้องการที่จะ:
- รันsudo -sหรือsudo -iถ้าคุณต้องการเชลล์ล็อกอิน (โปรดจำไว้ว่าหนึ่งในผลกระทบของsudo -iคือการเริ่มต้นคุณในไดเรกทอรีบ้านของรูท) หรือsudo bashถ้าคุณต้องการที่จะบังคับbashหรือสามารถส่งตัวเลือกไปยังเชลล์
- ทำงานในเปลือกใหม่cd directory
- การดำเนินการใด ๆ (อื่น ๆ ) จะต้องมีการดำเนินการเป็นรากในเปลือกใหม่
- เมื่อเสร็จแล้วให้เรียกใช้exitเพื่อออกจากเชลล์ใหม่ เป็นสิ่งสำคัญที่จะไม่ลืมสิ่งนี้เพราะคุณไม่ต้องการที่จะดำเนินการมากขึ้นในฐานะที่เป็นรากกว่าที่คุณตั้งใจ!
ดังนั้นหากคุณต้องการคุณสามารถเขียนฟังก์ชันเชลล์ (หรือสคริปต์) ที่ดำเนินการสองอย่างแรกของการกระทำเหล่านั้นเมื่อsudoมีการติดตามcdและจะทำงานsudoตามปกติ โปรดอย่าใช้สิ่งนี้เป็นทางเลือกในการเรียนรู้ว่าทำไม sudo cdไม่ประสบความสำเร็จเพราะถ้าคุณไม่เข้าใจว่าเกิดอะไรขึ้นคุณอาจจะสับสนมากเมื่ออยู่ในเชลล์ใหม่ (และคุณอาจไม่เข้าใจข้อความผิดพลาดใด ๆ ที่เกิดขึ้น)
ต่อไปนี้เป็นวิธีหนึ่งในการเขียนฟังก์ชันเชลล์ซึ่งจะเตือนคุณว่าคุณอยู่ในเชลล์ใหม่และคุณควรexitลบทิ้งเมื่อเสร็จแล้ว (เตือนว่ามีแนวโน้มที่จะเป็นประโยชน์สำหรับผู้ใช้ใด ๆระดับทักษะเพราะหนึ่งไม่ได้โดยทั่วไปคุ้นเคยกับการอยู่ในเปลือกใหม่เมื่อหนึ่งวิ่งsudoโดยไม่-s, -iหรือชื่อของเปลือกที่เกิดขึ้นจริงเป็นอาร์กิวเมนต์.)
# Make sudo treat "sudo cd [DIRECTORY]" as a special case and start a shell.
sudo() {
    if [ "$#" -eq 2 ] && [ "$1" = 'cd' ]; then
        sudo bash -c '
                if cd -- "$2"; then # When cd fails, its own message is enough.
                    printf "%s: Running %s shell in %s\n" "$0" "$USER" "$2" >&2
                    printf "%s: Type \"exit\" once you are done!\n" "$0" >&2
                    exec bash # Replace this bash shell with an interactive one.
                fi
            ' bash _ "$2" # Use $2 as the dir in the intermediate shell, too.
    else
        command sudo "$@"
    fi
}
คุณสามารถใส่สิ่งนี้ไว้ในของคุณ~/.bashrcแม้ว่านี่จะเป็นวิธีที่แปลกมากที่จะใช้sudoซึ่งคุณอาจต้องการเปิดใช้งานเป็นครั้งคราวเท่านั้น ในกรณีนั้นจะเป็นการดีกว่าถ้าวางไว้ในไฟล์ของตัวเอง ถ้าคุณสร้างไฟล์ที่เรียกว่าsudo.bashในไดเรกทอรีบ้านของคุณด้วยเนื้อหาเหล่านั้นแล้วคุณสามารถทำให้sudoฟังก์ชั่นที่มีอยู่ - เพื่อที่ว่ามันจะทำงานแทนปกติsudoคำสั่ง - . ~/sudo.bashโดยการทำงาน ที่มีผลในเชลล์ปัจจุบันและเชลล์ลูก แต่จะไม่ส่งผลกับเชลล์อื่น ด้วยเหตุผลเดียวกันว่าไฟล์ที่เหมือน.bashrcจะไม่ได้ปฏิบัติการที่ไม่ได้ทำเครื่องหมายปฏิบัติการด้วยsudo.bash chmodนี่เป็นห้องสมุดจริงๆแทนที่จะเป็นเชลล์สคริปต์แบบสแตนด์อโลน ถ้าคุณทำเรียกใช้เป็นเชลล์สคริปต์มันจะกำหนดฟังก์ชั่น ... แต่เฉพาะในเชลล์ที่รันสคริปต์ไม่ใช่สำหรับคุณในฐานะผู้โทร (แน่นอนคุณสามารถเขียนสคริปต์สำหรับสิ่งนี้ได้ซึ่งไม่ได้เกิดขึ้นกับแนวทางที่ฉันทำที่นี่)
ในการตรวจสอบและดูว่ามีการกำหนดในปัจจุบันเป็นฟังก์ชั่นเชลล์และดูความหมายในปัจจุบันถ้ามันเป็นหนึ่งในการเรียกใช้sudo type sudoการปิดใช้งาน (เช่น undefine) unset -f sudoฟังก์ชั่นเมื่อมีการกำหนดให้เรียกใช้ การทำงานด้วยตนเองปกติคำสั่งโดยตรงแม้ว่าฟังก์ชั่นเปลือกจะถูกกำหนดให้เรียกใช้sudo command sudoแต่โปรดทราบว่าคุณไม่ได้มีการทำอย่างนั้นเพราะsudoฟังก์ชั่นที่ไม่จริงว่าตัวเองเมื่อใดก็ตามที่มีมากขึ้นหรือน้อยกว่าสองข้อโต้แย้งผ่านไปหรืออาร์กิวเมนต์แรกผ่านไปคืออะไร cdแต่ นั่นเป็นเหตุผลที่คุณยังคงสามารถใช้งานได้ในรูปแบบปกติที่ผู้คนใช้sudo
ยังทราบว่าการทำงานของเชลล์ที่แสดงข้างต้นไม่ยังคงช่วยให้คุณผ่านการขัดแย้งอื่น ๆ เพื่อsudo, แต่ที่จะป้องกันไม่ให้การรักษาcdเป็นพิเศษ ไม่รองรับการทำงานเป็นพิเศษแม้ว่าคุณจะสามารถขยายฟังก์ชั่นเชลล์เพื่อรองรับเคสได้ ไม่เป็น เชลล์ที่มันสร้างนั้นคล้ายกับที่คุณได้รับมา รหัสไม่ทำงานจริงแต่ใช้ดังนั้นตัวเลือกทำงานอย่างถูกต้อง จริง ๆ แล้วมันจะทำงานสองครั้งเมื่อคุณผ่านและอาร์กิวเมนต์ของไดเรกทอรีไป เมื่อคุณเรียกใช้ก่อนอื่นมันจะทำการแยก bash shell ที่แยกต่างหากจากอันที่คุณใช้งานฟังก์ชั่นและเปลี่ยนไดเรกทอรี หากสำเร็จก็จะแทนที่sudo -u user cd directorysudo -i cd directorysudo -ssudo -ssudo bash-cbashcdsudo cd directorysudo bash shell นั้นใหม่ซึ่งเป็น interactive ที่คุณสามารถใช้ได้
นี่คือตัวอย่างของการที่เชลล์ทำงานโดยอัตโนมัติ "ทำสิ่งที่ถูกต้อง" สังเกตว่าsudo ls -A /rootพฤติกรรมปกติ เฉพาะเมื่อฉันพยายามcdไดเรกทอรีด้วยsudoเป็นเปลือกใหม่ที่สร้างขึ้นและฉันได้รับการเตือนอย่างชัดเจนว่าเกิดอะไรขึ้น
ek@Io:~$ sudo ls -A /root
[sudo] password for ek:
.aptitude      .bashrc  .config  .emacs.d  .nano     .rpmdb
.bash_history  .cache   .dbus    .local    .profile
ek@Io:~$ sudo -k  # invalidates my current timestamp... like I left for a while
ek@Io:~$ sudo cd /root/.local
[sudo] password for ek:
bash: Running root shell in /root/.local
bash: Type "exit" once you are done!
root@Io:/root/.local#
root@Io:/root/.local#
root@Io:/root/.local# exit
exit
ek@Io:~$
หากคุณพยายามที่sudo cdจะเป็นไดเรกทอรีที่คุณไม่สามารถเปลี่ยนเป็นรูทได้คุณจะได้รับข้อความแสดงข้อผิดพลาด:
ek@Io:~$ sudo cd /nonexistent
[sudo] password for ek:
bash: line 1: cd: /nonexistent: No such file or directory
ek@Io:~$ sudo -k
ek@Io:~$ sudo cd /etc/crontab
[sudo] password for ek:
bash: line 1: cd: /etc/crontab: Not a directory
ek@Io:~$
ฉันใช้sudo -kในระหว่างการร้องขอในตัวอย่างข้างต้นเพื่อแสดงว่ามันรับรองความถูกต้องคุณเป็นรูตก่อนที่จะพยายามเปลี่ยนไดเรกทอรี แต่คุณไม่จำเป็นต้องวิ่งsudo -kด้วยตัวเอง เนื่องจากฟังก์ชั่นเชลล์เป็นเพียง wrapper ที่บางสำหรับsudoคำสั่งจริงการแคชข้อมูลประจำตัวของคุณและsudoพฤติกรรมทั่วไปอื่น ๆยังคงทำงานได้ตามปกติ
แม้ว่ามันจะทำงานได้ดีและเรียบร้อยดี แต่ฉันยอมรับว่าการแรเงาsudoคำสั่งจริงด้วยฟังก์ชั่นที่มีชื่อเดียวกันนั้นแปลกมาก ผู้ใช้ส่วนใหญ่อาจจะเพียงต้องการที่จะดำเนินการขั้นตอนsudo -s, ตัวเอง แต่ในกรณีที่ทุกคนต้องการ - และเพื่อแสดงให้เห็นว่าเป็นไปได้ - มีcd directory
               
              
ls -lไดเรกทอรีของตัวเอง