Bash, jalankan perintah setelah memanggil shell baru

12

Saya mencoba membuat skrip seperti ini:

#!/bin/bash
sudo -s
something...

Ketika saya mengeksekusinya, saya mendapatkan shell baru tetapi somethingdieksekusi hanya ketika saya keluar dari shell yang dibuat oleh sudo -s, bukan di dalamnya.

Ada bantuan?

Matteo
sumber

Jawaban:

7

Masalahnya adalah sudo -stanpa argumen apa pun akan membuka shell interaktif untuk root.

Jika Anda hanya ingin menjalankan satu perintah menggunakan sudo -s, Anda dapat melakukannya:

sudo -s command

Sebagai contoh :

$ sudo -s whoami
root

Atau Anda dapat menggunakan string di sini:

$ sudo -s <<<'whoami'
root

Jika Anda memiliki banyak perintah, Anda dapat menggunakan di sini doc:

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--
heemayl
sumber
1
Ini tidak baik untuk digunakan sudo -skalau-kalau rootpengguna memiliki (agak miskin) ide untuk mengganti cangkangnya. Ini harus benar-benar sudo shmenyatakan secara eksplisit shell mana yang akan digunakan.
Michael Le Barbier Grünewald
7

Cara lain adalah dengan memberikan perintah bash penuh ke sudo:

#!/bin/bash
sudo bash -c 'command1; command2; command3;'

Namun, cara yang lebih baik akan meluncurkan skrip dengan sudosebaliknya. Ini bukan ide yang sangat bagus untuk ada sudodi dalam skrip. Jauh lebih baik untuk menjalankan seluruh skrip dengan root privilege ( sudo script.sh). Jika perlu, Anda bisa menggunakan sudountuk menjatuhkan hak istimewa untuk perintah tertentu. Sebagai contoh:

#!/usr/bin/env bash
whoami
echo $HOME
sudo -u terdon whoami  ## drop privileges for specific command.

Menjalankan skrip di atas menghasilkan:

$ sudo ~/scripts/a.sh
root
/root
terdon
terdon
sumber
3

The Bourne shell memiliki -cbendera yang dapat Anda gunakan untuk melewati script sewenang-wenang untuk shell, sehingga Anda dapat menulis sesuatu seperti

sudo sh -c 'something'

Namun ini hanya berguna untuk perintah yang paling sederhana, karena sangat sulit untuk mengutip skrip dengan benar dan ketidaknyamanan ini bahkan lebih tinggi jika Anda mengirim perintah ke server jauh melalui ssh karena skrip argumen akan dianalisis dua kali, sekali di samping mengirimkan skrip dan sekali di sisi menjalankan skrip.

Jika somethingskrip yang rumit atau perlu dilewatkan melalui ssh line, adalah praktik umum untuk menulis fungsi prepare_something_scriptyang tugasnya adalah menulis skrip 'sesuatu' di stdout . Dalam bentuknya yang paling sederhana, fungsi ini dapat menggunakan dokumen di sini untuk menghasilkan hasilnya:

prepare_something_script()
{
  cat <<EOF
something
EOF
}

Script yang dihasilkan oleh prepare_something_scriptkemudian dapat dieksekusi secara lokal dengan hak istimewa yang diberikan oleh sudo sebagai berikut:

prepare_something_script | sudo sh

Dalam skenario di mana skrip harus dijalankan dari jarak jauh dengan hak istimewa yang diberikan oleh sudo , biasanya untuk menyandikan skrip di basis 64 untuk menghindari mengarahkan input standar ssh , seperti ini:

something64=$(prepare_something_script | base64)
ssh usesr@remote-host "echo ${something64} | base64 --decode | sudo sh"

Jika Anda menggunakan kode itu dalam suatu fungsi, jangan lupa untuk menandai variabel something64 sebagai lokal . Beberapa implementasi base64 menawarkan -dflag untuk di-decode, yang kurang didukung dengan baik dibandingkan --decodevarian verbose . Beberapa implementasi perlu menambahkan -w 0perintah encoding untuk menghindari jeda baris palsu.

Michael Le Barbier Grünewald
sumber
0

Anda perlu menambahkan perintah di depan sudo -s, bukan di baris berikutnya.

sudo -s something...
Soumen
sumber