Truyền hàm cho người dùng khác trong Bash?


11

Có cách nào để tôi có thể chuyển Chức năng từ người dùng này sang người dùng khác không?

Ví dụ: tôi có một tập lệnh Bash nhỏ mà tôi thực thi là Root:

#!/bin/bash
user_func(){
  whoami
  exit
}
su vagrant -c 'user_func'

Tuy nhiên, Hàm user_func không được xác định cho người dùng Vagrant, chỉ dành cho Root và không thể được thực thi.

Tùy chọn khác của tôi sẽ có nhiều dòng

su vagrant -c 'cmd1' 
su vagrant -c 'cmd2'
, etc 

Hoặc, thực thi nhiều lệnh ex : su vagrant -c 'cmd1; cmd2; cmd3;', nhưng tôi không muốn có thừa, đặc biệt là khi cố gắng thực hiện hơn 5 lệnh với tư cách là người dùng Vagrant.

Có thể chuyển Hàm cho người dùng khác trong cùng một tập lệnh (ví dụ: không tạo tập lệnh trên đĩa dưới dạng người dùng khác và sau đó thực thi tập lệnh đã tạo đó)? Hoặc có một lựa chọn khác mà tôi đang xem?

Câu trả lời:


10

Âm thanh như bạn cần exportđịnh nghĩa chức năng đó đầu tiên:

#!/bin/bash
user_func (){
  whoami
  exit
}
export -f user_func
su vagrant -c 'user_func'

nên làm thủ thuật.

-fnói exportrằng đây là một tên hàm chứ không phải là một tên biến. Trích dẫn từ help export:

Đánh dấu mỗi TÊN để tự động xuất ra môi trường của các lệnh được thực hiện sau đó. ....

Tùy chọn:

 -f   refer to shell functions

Như được chỉ ra bởi peterph và Stephane trong các bình luận, điều này giả định hai điều:

  1. Rằng sulệnh của bạn sẽ không ghi đè lên môi trường của người dùng
  2. Đó vagrantlà vỏ đăng nhập bash. Nếu không, bạn có thể sử dụng sudòng lệnh thay thế được cung cấp bởi Stephane:

    su vagrant -c 'bash -c user_func'

Đây thực sự là chính xác những gì tôi đã hy vọng. Tôi đã không nhận ra rằng bạn sẽ có thể xuất hàm. Điều này hoạt động giống như tôi đã hy vọng nó sẽ sau khi chỉnh sửa tập lệnh mẫu. Cảm ơn!
gdieckmann 23/12/13

1
Đẹp, nhưng sẽ không hoạt động trong trường hợp sughi đè môi trường.
peterph

1
Lưu ý rằng nó chỉ hoạt động nếu vỏ đăng nhập vagrantbash. Nếu không,su vagrant -c 'bash -c user_func'
Stéphane Chazelas 23/12/13

6

Đó là một chút hackish, nhưng bạn có thể in định nghĩa của chức năng bên trong sommand được truyền đến suvà sau đó bạn tất nhiên có thể sử dụng nó.

$ function foo { do_some_stuff_here; }
$ su test -c "$(typeset -f foo); foo"

Điều này sẽ hoạt động ngay cả khi vì một lý do nào đó, môi trường của vỏ được sinh ra susẽ bị ghi đè, vì nó đặt định nghĩa sau khi khởi tạo shell. Nếu bạn viết hàm đủ tương thích, nó thậm chí sẽ hoạt động khi hai người dùng trong câu hỏi đang sử dụng các shell khác nhau.


+1 Thủ thuật thực sự gọn gàng! Tuy nhiên, chỉ là một câu hỏi, sumôi trường của vỏ có thể bị ghi đè bởi các yếu tố bên ngoài không? Ý tôi là, trong trường hợp này bạn có toàn quyền kiểm soát sudòng lệnh vì nó nằm trong một tập lệnh. Làm thế nào môi trường vỏ mới của nó có thể bị ghi đè?
Joseph R.

Ví dụ, vỏ sinh ra bởi sucó thể thực hiện một số khởi tạo môi trường. Ngoài ra, suchính nó cũng có thể tước bỏ một số môi trường của trình gọi để thắt chặt bảo mật một chút (mặc dù điều này thường được thực hiện bởi các lựa chọn thay thế mạnh hơn như sudo).
peterph

0

Đó không phải là một kịch bản bạn có, nó là một chức năng. Có vẻ như bạn muốn một kịch bản, mặc dù. Tạo một kịch bản phù hợp và đặt nó, khi nhu cầu của bạn yêu cầu, trong /usr/local/bin, hoặc trong /home/vagrant/bin, và hơn bạn sẽ có thể ví dụsu vagrant -c '/home/vagrant/bin/myscript.sh'


Đây là một chức năng trong một tập lệnh mẫu. Hy vọng của tôi là bao gồm mọi thứ tôi muốn làm trong tập lệnh đơn này (các lệnh chạy dưới dạng Root và với tư cách là người dùng Vagrant) và không phải có một tập lệnh riêng cho người dùng Root và tập lệnh riêng cho người dùng Vagrant.
gdieckmann 23/12/13

0

Một cách khác dễ di chuyển hơn để làm điều này (không phụ thuộc bash) là để tập lệnh của bạn tự gọi nó và thay đổi hành vi dựa trên ngữ cảnh (uid) hoặc tham số. các ví dụ về điều này được đưa ra trong tài liệu về supernơi chúng hiển thị một tập lệnh cần quyền root, tự gọi nó thông qua siêu khi không root.

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.