Làm thế nào để chạy hai lệnh trong sudo?


152

Có cách nào để tôi có thể chạy hai lệnh Db2 từ một dòng lệnh không? (Chúng sẽ được gọi từ một execlệnh PHP .)

  1. db2 connect to ttt (lưu ý rằng chúng ta cần có kết nối trực tiếp cho lệnh thứ hai
  2. db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

Tôi đã thử điều này:

sudo -su db2inst1 db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

Lệnh đầu tiên kết thúc chính xác nhưng lệnh thứ hai không thành công với thông báo lỗi SQL1024N A database connection does not exist. SQLSTATE=08003

Lưu ý rằng tôi cần chạy cái này với tư cách là người dùng php. Lệnh sudo -u db2inst1 idnhư người dùng php cung cấp cho tôi đầu ra chính xác.


vui lòng để lại một bình luận tại sao bạn muốn đóng câu hỏi này. Cảm ơn bạn.
Radek

1
Việc bỏ phiếu chặt chẽ là để di chuyển đến serverfault, vì đây là câu hỏi quản trị hệ thống, không phải lập trình.
bdonlan

Câu trả lời:


157

sudo có thể chạy nhiều lệnh thông qua shell, ví dụ:

$ sudo -s - 'whoami; tôi là ai'
nguồn gốc
nguồn gốc

Lệnh của bạn sẽ là một cái gì đó như:

sudo -u db2inst1 -s - "db2 kết nối với ttt; db2 CẬP NHẬT LIÊN HỆ THIẾT LẬP EMAIL_ADDRESS = 'mytestaccount@gmail.com'"

Nếu phiên bản sudo của bạn không hoạt động với dấu chấm phẩy có -s (rõ ràng, nó không nếu được biên dịch với một số tùy chọn nhất định), bạn có thể sử dụng

sudo - sh -c 'whoami; tôi là ai'

thay vào đó, về cơ bản làm điều tương tự nhưng làm cho bạn đặt tên rõ ràng.


12
điều này không hoạt động trên bash debian ổn định (bóp) mới nhất:sudo -s -- '/usr/bin/whoami; /usr/bin/whoami' /bin/bash: /usr/bin/whoami; /usr/bin/whoami: No such file or directory
Valor

11
@Valor bạn có thể sử dụng sudo -- sh -c 'whoami; whoami;như một cách giải quyết khi "sudo -s" bị hỏng. Tôi cũng đã cập nhật câu trả lời.
wjl

6
+1 cho phiên bản đã chỉnh sửa hiển thị ví dụ "- sh -c". Cảm ơn!
JD.

4
Bạn có thể vui lòng giải thích lý do tại sao bạn cần "-"?
Vic Seedoubleyew

7
@VicSeedoubleyew Chỉ --ra kết thúc của các tham số sudo, vì vậy mọi thứ khác là một phần của lệnh; không có nó, các đối số như -ccó thể được hiểu là một đối số sudo. Điều này hoạt động cho hầu hết (nhưng không phải tất cả) các chương trình dòng lệnh. Đối với một sudoví dụ khác (không phải ), để xóa một tệp có tên -fbạn không thể chạy rm -f, phải không?! Nhưng bạn có thể chạy rm -- -fđể xóa tập tin được gọi -f.
wjl

176

Đối với lệnh của bạn, bạn cũng có thể tham khảo ví dụ sau:

sudo sh -c 'whoami; whoami'


14
Tôi đã tìm thấy điều này một sự thay thế đáng tin cậy hơn.
Nick


42

Nếu bạn muốn xử lý dấu ngoặc kép:

sudo -s -- <<EOF
id
pwd
echo "Done."
EOF

4
Đây là câu trả lời sạch nhất ở đây, cảm ơn. Có thể thêm một ghi chú "Bạn không thể chạy nhiều lệnh từ sudo- bạn luôn cần phải lừa nó để thực thi một trình bao có thể chấp nhận nhiều lệnh để chạy như tham số"
trs

8

Một cách khác evalđể tránh sử dụng subshell:

sudo -s eval 'whoami; whoami'

Lưu ý: Các câu trả lời khác sử dụng sudo -skhông thành công vì các trích dẫn đang được chuyển sang bash và chạy dưới dạng một lệnh duy nhất vì vậy cần phải loại bỏ các trích dẫn bằng eval. evalđược giải thích tốt hơn là câu trả lời SO này

Trích dẫn trong các lệnh cũng dễ dàng hơn:

$ sudo -s eval 'whoami; whoami; echo "end;"'
root
root
end;

Và nếu các lệnh cần dừng chạy nếu một lỗi không sử dụng ký hiệu kép thay vì dấu hai chấm:

$ sudo -s eval 'whoami && whoamit && echo "end;"'
root
/bin/bash: whoamit: command not found

3

Các -stùy chọn đã không làm việc cho tôi, -iđã làm.

Đây là một ví dụ về cách tôi có thể cập nhật kích thước nhật ký từ bash của mình:

sudo -u [user] -i -- sh -c 'db2 connect to [database name];db2 update db cfg for [database name] using logsecond 20;db2 update db cfg for [database name] using logprimary 20;'

1

Trên thiết bị đầu cuối, gõ:

$ sudo bash

Sau đó viết nhiều lệnh như bạn muốn. Nhập exitkhi bạn thực hiện.

Nếu bạn cần tự động hóa nó, hãy tạo một script.shtệp và chạy nó:

$ sudo ./script.sh

1

Trong một chủ đề hơi liên quan, tôi muốn thực hiện cùng một sudo đa lệnh thông qua SSH nhưng không có cách nào ở trên hoạt động.

Ví dụ trên Ubuntu,

$ ssh host.name sudo sh -c "whoami; whoami"
[sudo] password for ubuntu:
root
ubuntu

Thủ thuật được phát hiện ở đây là trích dẫn hai lần lệnh.

$ ssh host.name sudo sh -c '"whoami; whoami"'
[sudo] password for ubuntu:
root
root

Các tùy chọn khác cũng hoạt động:

ssh host.name sudo sh -c "\"whoami; whoami\""
ssh host.name 'sudo sh -c "whoami; whoami"'

Về nguyên tắc, dấu ngoặc kép là cần thiết bởi vì tôi nghĩ trình vỏ máy khách nơi SSH được chạy sẽ tách dải trích dẫn ngoài cùng. Trộn và kết hợp các trích dẫn với nhu cầu của bạn (ví dụ: các biến cần được truyền vào). Tuy nhiên YMMV với dấu ngoặc kép đặc biệt nếu các lệnh từ xa phức tạp. Trong trường hợp đó, một công cụ như Ansible sẽ đưa ra lựa chọn tốt hơn.


1

Nếu bạn biết mật khẩu root, bạn có thể thử

su -c "<command1> ; <command2>"  

Nếu bạn không biết mật khẩu root, hãy sử dụng sudo su -c "<command1> ; <command2>" .
Dag Høidahl

0

Các câu trả lời trên sẽ không cho phép bạn trích dẫn bên trong dấu ngoặc kép. Giải pháp này sẽ:

sudo -su nobody umask 0000 \; mkdir -p "$targetdir"

Cả lệnh umask và lệnh mkdir đều chạy với người dùng 'không ai'.


Bạn có thể sử dụng dấu ngoặc đơn và dấu ngoặc kép và thoát chúng.
Radek

Ok, vậy tại sao, bây giờ vấn đề tôi đặt ô trong lệnh này, nó không có tác dụng gì?
Michael
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.