Truy cập mã thoát bên ngoài su -m $ USER -c Cấp <cmd> '


8

Lệnh dưới đây in "0" hoặc "1" chính xác tùy thuộc vào thất bại hay không vì tôi đặt $? bên trong lệnh "su".

sudo su -m $USER -c "./shutdown.sh &> /dev/null; echo \$?"

Tuy nhiên, nếu tôi làm điều này:

sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null"; echo $?

nó sẽ luôn in "0" vì "su" thực tế sẽ luôn thành công, ngay cả khi phần lệnh bị lỗi.

Bất kỳ ý tưởng làm thế nào tôi có thể lấy mã thoát của subshell?

Câu trả lời:


7

Tôi chỉ sửa gần như chính xác tình huống tương tự. Hy vọng nó vẫn giúp bạn, nếu không thì có lẽ người khác. Tôi đã bắt đầu từ su, không phải sudo, nhưng vì sudo dự định bọc một lệnh khác, nên nó thực sự phải chuyển tiếp mã thoát của su. Nếu không, bạn cũng có thể áp dụng bản sửa lỗi bên dưới ở cấp độ sudo.

Giống như bạn lưu ý vấn đề chính là su thành công thực thi lệnh của nó. Hành động mặc định sau đó là báo cáo rằng nó đã hoàn thành mà không gặp vấn đề gì và do đó, nó trả về mã thoát 0. Nó không "biết" rằng mã thoát không 0 từ một lệnh là bất ngờ, hoặc nó nên làm gì đó với nó. Do đó, giải pháp khá đơn giản là làm cho su trả về mã thoát của lệnh cuối cùng. Điều này đã làm cho tôi

su <user_x> -c '<bunch_of_commands>; exit $?'

Trong trường hợp sudo không chơi tốt, toàn bộ lệnh sẽ giống như thế này (tôi sẽ kiểm tra điều này cho bạn nhưng tôi chưa cài đặt sudo)

sudo 'su <user_x> -c \'<bunch_of_commands>; exit $?\'; exit$?'

Theo dõi các dấu ngoặc kép và đảm bảo $? không được mở rộng, vì vậy không có dấu ngoặc kép.


2

Echo giá trị trả về bên trong lệnh và truy cập bên ngoài bằng cách gán toàn bộ lệnh cho một biến (sử dụng một lớp con.)

RETVAL=$(sudo su -m $USER -c "./shutdown.sh &> /dev/null; echo \$?")
echo $RETVAL

0

Bạn luôn có thể sử dụng tệp tmp:

$ sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null; echo \$? > /tmp/exit_code"; cat /tmp/exit_code

Vâng, đây là những gì tôi đang làm ngay bây giờ, nhưng tôi đã hy vọng không dựa vào một tập tin tmp.
Nick

0

Điều này hoạt động trong các vỏ Zsh / Bash / Bourne:

$ sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null"
$ echo $?

Tôi không chắc tại sao mã trả lại không có sẵn khi bạn yêu cầu nó trong một lớp lót, nhưng nó có sẵn khi bạn sử dụng nhiều hơn một dòng để làm điều tương tự.


Điều này thực sự không chính xác. Điều này sẽ luôn trả về 0 vì "su -m $ USER -c <cmd>" sẽ luôn thành công ngay cả khi lệnh thực tế trong đó không có.
Nick

1
@Nick - Nó hoạt động ở đây. Đầu ra của bạn là gì? Hãy thử sudo su -m zero2cx -c "/bin/false &> /dev/null"nhưng với tên người dùng hệ thống của bạn. $?nên là '1'.
zero2cx

Yup, với tên người dùng của riêng tôi, nó trả về "1" như mong đợi. Nhưng tôi đang cố gắng sử dụng điều này để chạy một ứng dụng thông qua người dùng của chính nó chứ không phải root hay bất kỳ người dùng nào khác.
Nick

@Nick - Nó sẽ hoạt động với $ USER=appusernamethiết lập như bạn muốn. Không sử dụng tên người dùng thực sự, chưa đọc sử dụng dự định của bạn appusername. Nó nên làm việc, nó làm cho tôi.
zero2cx
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.