Mengakses kode keluar di luar su -m $ USER -c “<cmd>”

8

Perintah di bawah ini mencetak "0" atau "1" dengan benar tergantung pada kegagalan atau tidak karena saya menaruh $? di dalam perintah "su".

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

Namun, jika saya melakukan ini:

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

itu akan selalu mencetak "0" karena "su" yang sebenarnya akan selalu berhasil, bahkan jika bagian perintah gagal.

Adakah yang tahu bagaimana saya dapat mengambil kode keluar dari subkulit?

Nick
sumber

Jawaban:

7

Saya baru saja memperbaiki situasi yang hampir persis sama. Semoga masih bisa membantu Anda, jika tidak maka mungkin orang lain. Saya mulai dari su, bukan sudo, tetapi karena sudo dimaksudkan untuk membungkus satu perintah lain, itu benar-benar harus menyampaikan kode keluar su. Jika tidak, Anda dapat menerapkan perbaikan di bawah ini pada level sudo juga.

Seperti yang Anda perhatikan, masalah utamanya adalah su berhasil mengeksekusi perintahnya. Tindakan default adalah untuk melaporkan bahwa itu selesai tanpa masalah dan karenanya mengembalikan kode keluar 0. Tidak "tahu" bahwa kode keluar 0 dari suatu perintah tidak terduga, atau bahwa ia harus melakukan sesuatu dengan itu. Jadi solusinya cukup sederhana untuk membuat su mengembalikan kode keluar dari perintah terakhirnya. Ini berhasil untukku

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

Dalam hal sudo tidak bermain bagus, seluruh perintah harus seperti ini (saya akan memeriksa ini untuk Anda tetapi saya tidak menginstal sudo)

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

Perhatikan nesting kutipan dan pastikan $? tidak diperluas, jadi tidak ada tanda kutip ganda.

Kapten Coder
sumber
2

Gema nilai kembali di dalam perintah dan akses ke luar dengan menetapkan seluruh perintah ke variabel (menggunakan subkulit.)

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

Anda selalu dapat menggunakan file tmp:

$ sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null; echo \$? > /tmp/exit_code"; cat /tmp/exit_code
terdon
sumber
Ya, ini yang saya lakukan sekarang, tapi saya berharap tidak bergantung pada file tmp.
Nick
0

Ini bekerja di shell Zsh / Bash / Bourne:

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

Saya tidak yakin mengapa kode pengembalian tidak tersedia ketika Anda memintanya dalam satu-liner, tetapi tersedia ketika Anda menggunakan lebih dari satu baris untuk melakukan hal yang sama.

nol2cx
sumber
Ini sebenarnya tidak benar. Ini akan selalu menghasilkan nol karena "su -m $ USER -c <cmd>" akan selalu berhasil walaupun perintah aktual di dalamnya tidak.
Nick
1
@Nick - Ini bekerja di sini. Apa output Anda? Coba sudo su -m zero2cx -c "/bin/false &> /dev/null"tetapi dengan nama pengguna sistem Anda. $?harus '1'.
zero2cx
Yup, dengan nama pengguna saya sendiri ia mengembalikan "1" seperti yang diharapkan. Tapi saya mencoba menggunakan ini untuk menjalankan aplikasi melalui penggunanya sendiri dan bukan root atau pengguna lain.
Nick
@Nick - Ini harus bekerja dengan $ USER=appusernameset yang Anda inginkan. Jangan gunakan nama pengguna asli, masukkan menggunakan yang Anda maksudkan appusername. Itu harus bekerja, itu untuk saya.
zero2cx