Làm cách nào tôi có thể nhận các lệnh sudo để sử dụng các cài đặt trong /root/.bashrc


9

Tôi đã tùy chỉnh .bashrcvới một số bí danh, cụ thể llexport LS_OPTIONS='--color=auto'

Thật không may, điều này không hoạt động khi được sử dụng sudo, vì vậy tôi cũng đã sửa đổi /root/.bashrc, nhưng điều này dường như không có sự khác biệt.

sudo envchương trình HOME=/rootSHELL=/bin/bash

Làm thế nào tôi có thể nhận sudolệnh để sử dụng các cài đặt trong /root/.bashrc?

Tôi hiểu rằng điều này chỉ xảy ra khi bashđược thực hiện tương tác, vì vậy tôi mở cho bất kỳ đề xuất nào khác về cách tùy chỉnh.


@ daniel-gelling - Tôi luôn cảm thấy Q này là một vấn đề XY - meta.stackexchange.com/questions/66377/what-is-the-xy-probols . Tiêu đề ngụ ý họ muốn bất cứ điều gì ngoài /root/.bashrcthực sự những gì Q đặt sau là bí danh từ tệp này - điều này là không thể đối với điều này - unix.stackexchange.com/questions/1496/ .
slm

@slm Những gì tôi sau khi thêm một phương thức vào bashrc - như tôi đã thực hiện trong tệp .bashrc cá nhân cũng như tệp .bashrc để root để "vô hiệu hóa" -rtùy chọn cho crontab: crontab () { [[ $@ =~ -[iel]*r ]] && echo '"r" not allowed' || command crontab "$@" ;}. Điều này hoạt động khi đăng nhập với tư cách là một người dùng, tuy nhiên khi tôi thực thi sudo crontab -rthì nó vẫn thực thi.
Daniel Gelling

@DanielGelling - xem câu trả lời của tôi có phù hợp với kịch bản của bạn không.
slm

Câu trả lời:


6

sudochạy một thực thi, không phải là một lệnh shell. Vì vậy, nó không biết về bí danh. Nếu bạn chạy sudo ls, điều đó giống như sudo /bin/ls, nó không sử dụng bất kỳ lsbí danh nào bạn có thể có.

Bạn có thể gây ra sudo lsđể mở rộng bí danh bằng cách đặt các mục sau vào .bashrc:

alias sudo='sudo '

Lưu ý không gian dấu - cho biết trình bao tiếp tục mở rộng bí danh với từ đi sau sudo. Coi chừng việc mở rộng bí danh sau sudo có thể không phải lúc nào cũng là một ý tưởng hay, nó phụ thuộc vào loại bí danh nào bạn có.

Hơn nữa, sudo loại bỏ hầu hết các biến khỏi môi trường. Điều này sẽ không ảnh hưởng đến một bí danh như alias ls='ls $LS_OPTIONS', bởi vì đó là một biến shell được sử dụng bởi shell trong khi nó mở rộng lệnh (và xuất nó từ .bashrckhông phục vụ mục đích nào). Nhưng nó sẽ ảnh hưởng đến các biến được sử dụng bởi lệnh, chẳng hạn như LS_COLORS. Bạn có thể định cấu hình sudo để giữ các biến môi trường nhất định bằng cách chỉnh sửa cấu hình của nó: chạy visudovà thêm dòng

Defaults env_keep += "LS_COLORS"

Với các cài đặt này, sudo llsẽ cung cấp cho các màu bạn đã sử dụng.

Ngoài ra, bạn có thể chạy một vỏ gốc với sudo -s. Shell này sẽ tải tập tin cấu hình của nó ( ~/.bashrccho bash). Tùy thuộc vào cách sudo được cấu hình, điều này có thể HOMEđược đặt thành thư mục chính của bạn hoặc thay đổi nó thành /root. Bạn có thể buộc thư mục chính được đặt thành root sudo -Hs; ngược lại, để giữ thư mục gốc, chạy sudo env HOME="$HOME" bash.


3

Cảm ơn những người đã trả lời, những người nhắc tôi đọc man sudokỹ hơn.

sudo -s Nếu không có lệnh nào được chỉ định, shell tương tác được thực thi.

Shell tương tác này sử dụng /root/.bashrcvà do đó bao gồm các tùy chỉnh của tôi.

Nó yêu cầu lệnh được nhập riêng, nhưng điều này là OK.


2

Lý lịch

Tôi luôn cảm thấy câu hỏi này là một vấn đề XY . Tiêu đề ngụ ý họ muốn bất cứ điều gì ngoài /root/.bashrcthực sự câu hỏi đặt ra là bí danh từ tệp này - điều này được nhiều người tin là không thể thực hiện được - Tại sao tập lệnh Bash của tôi không nhận ra bí danh? .

Về cơ bản, theo thiết kế, các bí danh của bạn sẽ không được chọn sudoở những nơi khác vì chúng không thể mang theo được và đây cũng là ý kiến ​​của tôi về chúng.

Bất cứ điều gì trong môi trường người dùng không nên được giả sử bởi các tập lệnh và bất kỳ phần mềm nào có thể chạy trên một hộp nhất định. Nhưng tôi nhận ra rằng có những kịch bản có thể có một số bí danh trong một tài khoản người dùng nhất định $HOME/.bashrcmà những người khác có thể muốn tận dụng trong các kịch bản tương tác.

Để đạt được điều đó, bạn có thể chỉ cần yêu cầu trình thông dịch Bash mở rộng bất kỳ bí danh nào mà nó tìm thấy trong quá trình đăng nhập bên ngoài các hành vi shell thông thường mà bạn gặp phải khi sử dụng sudo.

Thí dụ

Thiết lập

Để thiết lập mọi thứ, tôi đã thêm các bí danh, biến môi trường và hàm sau vào tập tin /root/.bashrcvà người dùng gốc của mình /root/.bash_profile.

$ grep smurf ~/.bashrc
alias brc_smurf='echo "ran alias from /root/.bashrc"'
export brc_smurf_env='var from /root/.bashrc'
bpf_smurf_func() { echo 'ran func from /root/.bash_profile'; }

$ grep smurf ~/.bash_profile
alias bpf_smurf='echo "ran alias from /root/.bash_profile"'
export bpf_smurf_env='var from /root/.bash_profile'
brc_smurf_func() { echo 'ran func from /root/.bashrc'; }

Không làm bất cứ điều gì cả hai công việc này (không có gì ngạc nhiên):

$ sudo brc_smurf
sudo: brc_smurf: command not found

$ sudo bpf_smurf
sudo: bpf_smurf: command not found

Chúng tôi thấy rằng aliaslệnh hiển thị không có bí danh khi chạy trong sudo:

$ sudo alias
$

Hành vi này là gợi ý của bạn mà bạn không nên mong đợi bí danh có thể truy cập được. Nhưng chúng tôi tiếp tục ...

Bước # 1 - bí danh hiển thị

Nếu chúng ta chạy, bash -cichúng ta có thể khiến Bash ít nhất đọc $HOME/.bashrc:

$ sudo bash -ci 'alias' | grep smurf
alias brc_smurf='echo "ran alias from /root/.bashrc"'

Thật tuyệt, vậy có lẽ chúng ta có thể chạy nó?

$ sudo bash -ci 'alias; brc_smurf'
bash: alias; brc_smurf: No such file or directory

Bước 2 - shopt -s expand_aliases

Không. Một lần nữa, đây là do thiết kế, chúng tôi đang làm một việc mà chúng tôi không cho là đang làm, vì vậy có một số "két sắt" mà chúng tôi phải vô hiệu hóa. "an toàn" khác là Bash.

$ sudo bash -ci 'shopt -s expand_aliases; alias; brc_smurf'
alias brc_smurf='echo "ran alias from /root/.bashrc"'
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
ran alias from /root/.bashrc

Ở đây chúng tôi có thể thấy thông điệp của /root/.bashrcchúng tôi, chúng tôi đã thực hiện thành công bí danh người dùng root brc_smurf.

Bước # 3 - những gì về env vars?

Nếu bạn đang sử dụng phương pháp hiển thị ở trên thì giờ đây cũng sẽ hoạt động.

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env'
ran alias from /root/.bashrc
var from /root/.bashrc

Bước # 4 - còn chức năng thì sao?

Những công việc này quá mong đợi:

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env;brc_smurf_func'
ran alias from /root/.bashrc
var from /root/.bashrc
ran func from /root/.bashrc

TLDR;

Bạn có thể làm điều này để có quyền truy cập vào các biến môi trường + bí danh từ /root/.bashrc:

$ sudo bash -ci 'shopt -s expand_aliases; <cmds>'

Đi đường

Phương pháp này cho phép nội dung của /root/.bashrc, nó không nhận nội dung của /root/.bash_profile.

Người giới thiệu


Đúng, mặc dù có một số khác biệt nhỏ giữa chúng, chúng ta không đi sâu vào chi tiết ở đây ;-). Dù sao, bạn có thể giúp tôi với tình huống tôi đã nêu trong các bình luận của câu hỏi: sử dụng các hàm trong .bashrcvới sudo; cụ thể loại bỏ các -rtùy chọn từ crontab?
Daniel Gelling

Được rồi, nhưng điều này sẽ có nghĩa là tôi sẽ phải chạy: sudo bash -ci 'alias; shopt -s expand_aliases; echo $brc_smurf_env'thay vì một đơn giản sudo echo $brc_smurf_env?
Daniel Gelling

Bạn có thể xóa alias, điều đó chỉ đơn giản là để hiển thị chúng, bạn cần phải làmsudo bash -ci 'shopt -s expand_aliases; <cmds>'
slm

Đó sẽ là rất nhiều gõ chỉ để chỉnh sửa crontab của tôi cho root. Hãy để tôi tạo một bí danh cho nó :-P
Daniel Gelling

@DanielGelling - yup, chào mừng bạn đến với tất cả những niềm vui trong ruột.
slm

0

Có một loạt các cài đặt trong tệp / etc / sudoers cụ thể hoặc thiết lập môi trường khi các lệnh sudo được chạy (ví dụ: Đảm bảo PATH chỉ có các vị trí đáng tin cậy) nhưng tùy thuộc vào những gì bạn hy vọng thoát khỏi điều này bạn có thể không thực hiện được những gì bạn đang làm nếu nó liên quan đến việc chạy các lệnh thực tế trong trình bao để thiết lập môi trường. Sudaging đặc biệt không cung cấp cho bạn một vỏ đăng nhập gốc để nó không thiết lập hồ sơ thường xuyên cho bạn.


0

Hãy nói rằng chúng tôi chỉnh sửa /root/.bashrc thành:

$ sudo su -
Password: ******
# cat ~/.bashrc

echo "root bashrc file was read"
PATH=~/bin:$PATH
echo "$PATH"
export USERVAR=set
echo "$USERVAR"

umask 022
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'

Cho phép đăng xuất và đăng nhập lại để làm cho bash đọc tệp:

# exit
$ sudo su -
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@here:~# alias l
alias l='ls $LS_OPTIONS -lA'
root@here:~# 

Như bạn có thể thấy, tập tin đã được đọc, PATH đã được thay đổi và các bí danh đã được đặt. Tất cả là chức năng như bạn yêu cầu.

Tuy nhiên, sudo vẫn không hoạt động như bạn mong đợi.

root@here:~# exit
$ sudo env | grep USERVAR              # no output 
$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PATH không thay đổi. Có thể có cách để thay đổi đường dẫn trong sudoers, nhưng tôi thực sự khuyên bạn nên tránh làm điều đó. Và, dù sao, bí danh, chức năng và một số thay đổi khác vẫn sẽ không được áp dụng bằng cách chỉ thay đổi PATH. Một tập tin cần phải có nguồn gốc. Làm điều đó cho mọi tập lệnh hoặc lệnh sẽ yêu cầu máy tính thực hiện nhiều công việc hơn mà không có bất kỳ lợi ích thực sự nào. Script không sử dụng bí danh (không có sử dụng thực tế cho chúng bên trong script).

Vì vậy, chỉ cần đăng nhập, .bashrc tập tin sẽ được tải tự động và hoạt động.

Bạn có thể bắt đầu bash như thế này:

$ sudo bash
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@mail:/home/isaac/me/temp/clocks-master#

Nhưng như bạn thấy ở trên, pwd (thư mục làm việc) đã không thay đổi và nếu bạn kiểm tra thêm một chút, một số cài đặt khác cũng không thay đổi. Đó là lý do tại sao lệnh chính xác là sử dụng:

$ sudo su -

Nếu lệnh đó quá dài để gõ, hãy tạo bí danh hoặc hàm trong người dùng (không phải root) nơi lệnh đó sẽ được sử dụng, đại loại như:

$ alias mysu='sudo su -'
$ mysu
# 

0

TL; DR: Bạn có thể sử dụng sudo -iđể chạy một hàm được xác định /root/.bashrc(nhưng không phải là bí danh) và cũng có quyền truy cập vào các biến được xuất từ ​​tệp đó:

đối số lệnh sudo -i 

Tuy nhiên, bí danh không hoạt động ở đó, nhưng bạn có thể dễ dàng chuyển đổi chúng thành các chức năng nếu bạn muốn cung cấp chúng cho sudo -i .

Đọc để phân tích đầy đủ và biết thêm chi tiết.


Có một vài vấn đề ở đây, một số về cách thức hoạt động của sudo và một số cách thức hoạt động của bash ...

Theo mặc định, sudosẽ chỉ tìm kiếm các lệnh và sẽ bỏ qua trình bao, vì vậy chỉ cần chạy sudo llsẽ chỉ hoạt động nếu có một lltệp thực thi trong một trong các thư mục trong $PATH. Vì vậy, để sử dụng bí danh (hoặc hàm), bạn cần đảm bảo một shell được gọi như một phần của quy trình.

Một cách sẽ là chạy một cái gì đó như sudo shhoặc sudo bash, mặc dù hiện đại sudo(tôi đang thử nghiệm điều này trên sudo 1.8.19p1) có các tùy chọn -s-i cho mục đích đó.

Vì vậy, một lần thử sẽ là một cái gì đó giống như sudo -s ll(tương đương với sudo bash -c 'll', giả sử bạn $SHELLlà Bash, dường như là trường hợp dựa trên những rcfilegì bạn đã đề cập.) Nhưng điều đó cũng không hoạt động, vì nó khởi động vỏ trong một không tương tác, chế độ không đăng nhập, không đọc bất kỳ tệp khởi động nào của nó. Về cơ bản, nó giống như khi bạn viết một kịch bản shell và sử dụng #!/bin/bashđể chạy nó. Các bí danh (và chức năng) bạn có trong~/.bashrc tệp không thể truy cập được từ tập lệnh đó ...

Vì vậy, tiếp theo là -itùy chọn, tạo ra một vỏ đăng nhập. Điều đó hứa hẹn hơn, vì nó sẽ đọc các tệp khởi động của bạn! Tuy nhiên, sudo -i ll(tương đương sudo bash -l -c 'll') vẫn sẽ không hoạt động. Vì vậy, làm thế nào là có thể, cho nó đã đọc định nghĩa củall bí danh?

Vâng, lời giải thích tiếp theo ở đây là, theo mặc định, bash sẽ không mở rộng bí danh, ngoại trừ khi shell tương tác ... Shell này bắt đầu bởi sudo -i(hoặc bash -l) là một vỏ đăng nhập , nhưng vẫn không tương tác.

Vì vậy, bước tiếp theo là để có được một vỏ tương tác , sau đó hoạt động :

sudo bash -i -c 'll'

(Có cả đăng nhậptương tác cũng tốt, tất nhiên, bash -l -i -c ...sẽ hoạt động.)

Một cách khác là tiếp tục sử dụng shell đăng nhập (không tương tác) nhưng yêu cầu rõ ràng để mở rộng bí danh, vì vậy điều này cũng sẽ hoạt động:

sudo bash -l -O expand_aliases -c 'll'

(Trường hợp bash tương tác không cần shell đăng nhập , vì điều đó đủ để đọc các tệp khởi tạo, nhưng cái này cần -lđọc chúng.)

Đây là những dòng lệnh khá dài ... Và chúng cũng yêu cầu bạn trích dẫn toàn bộ lệnh shell, vì vậy nếu bạn gọi một bí danh bằng các đối số, bạn sẽ phải biến tất cả thành một chuỗi ... Vì vậy, đó là loại vụng về sử dụng ...

Lưu ý rằng trước đó tôi đã nói về bí danh và chức năng ... Đó là mục đích, vì các chức năng thực sự thuận tiện hơn rất nhiều ở đây. Bạn không cần bất cứ điều gì đặc biệt (chẳng hạn như có vỏ tương tác hoặc đặt tùy chọn cụ thể) để thực thi các chức năng trên vỏ, miễn là bạn tìm nguồn cung cấp định nghĩa của chúng.

Vì vậy, nếu bạn xác định llhàm thay vì bí danh, bạn có thể sử dụng trực tiếp với -iphím tắt của sudo :

sudo -i ll

Và nếu bạn có một dòng lệnh dài hơn, với các đối số, bạn cũng có thể chuyển chúng trực tiếp tại đây:

sudo -i ll -C -R /etc

(So ​​sánh với sudo bash -i -c 'll -C -R /etc'.)

Các chức năng cũng linh hoạt hơn rất nhiều và thường dễ bảo trì hơn ... Thông thường dễ dàng chuyển đổi bí danh thành một chức năng, lưu ý duy nhất là luôn luôn sử dụng "$@"khi bạn muốn thực hiện các đối số bổ sung (thường là vào cuối của bí danh.)

Ví dụ: bí danh này:

alias ll='ls $LS_OPTIONS -l'

Có thể được chuyển thành chức năng này:

ll () {
    ls $LS_OPTIONS -l "$@"
}

Họ, cho hầu hết các mục đích, tương đương. Và, như đã đề cập trước đó, chức năng nên được truy cập trực tiếp từ đó sudo -i, vì vậy đó là phần thưởng bổ sung.

Tôi hy vọng bạn tìm thấy câu trả lời và giải thích này hữu ích!


DV - Tôi không cảm thấy như điều này đang cải thiện tình hình nữa so với những gì đã có ở đây.
slm

1
@slm Tôi nghĩ rằng câu trả lời của tôi là thêm một cái gì đó, vì không có câu trả lời trước nào đề cập đến biểu mẫu sudo -i command argumentsđể có thể chạy các chức năng từ đó /root/.bashrcvà có sẵn các biến xuất. Nhưng tôi thấy câu trả lời của tôi có lẽ quá dài và thông tin đó có phần bị chôn vùi trong đó ... Vì vậy, tôi đã thêm một TL; DR để tóm tắt nó (trong khi vẫn giữ các chi tiết kỹ thuật của cuộc điều tra xung quanh.) Xin hãy xem lại.
filbranden
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.