Bagaimana cara meningkatkan hak istimewa di tengah jalur pipa?

8

Dugaan saya adalah sebagai berikut:

echo "Generating some text" | su - -c cat >/output/file

Tetapi sumengatakan:

su: must be run from a terminal

Apa yang akan kamu lakukan?

x-yuri
sumber
Jika Anda menemukan solusinya sendiri, silakan tambahkan sebagai jawaban di bawah ini.
Braiam
@Braiam Solusinya tidak layak menjadi jawaban.
x-yuri

Jawaban:

8

sudo mendukung ini.

$ echo hello world | sudo cat  
SUDO password: 
hello world

Perbedaannya adalah yang sudomeminta kata sandi pengguna Anda, bukan kata sandi root(target user). Namun jika Anda menginginkannya, Anda dapat mengubah perilaku ini dengan targetpw(atau runaspwatau rootpw) arahan dalam sudoers.conf.


Namun membaca apa yang Anda coba lakukan, sementara ini menyelesaikan masalah peningkatan izin, itu tidak akan melakukan apa yang Anda harapkan. Makna /output/filetidak akan dibuat sebagai pengguna root, itu akan dibuat / dimodifikasi sebagai pengguna Anda.

Alasan untuk ini adalah bahwa redirection output shell dilakukan sebelum menjalankan perintah. Jadi shell terbuka /output/filedan meneruskan file yang dibuka ke su/ sudo(dan akibatnya, cat).

Namun Anda dapat menggunakannya teeuntuk melakukan ini sebagai gantinya, karena teeutilitas akan membuka file itu sendiri.

echo "hello world" | sudo tee /output/file >/dev/null

Pada dasarnya teemenyalin output ke /output/filedan STDOUT, namun STDOUT diarahkan ke /dev/null.

Anda juga bisa:

echo "hello world" | sudo sh -c 'cat > /output/file'

... yang kurang samar.

Patrick
sumber
Anda juga dapat "cache" peningkatan hak dengan meminta sudo -v. Ini akan menanyakan kata sandi Anda jika Anda belum menggunakan sudo dalam beberapa menit.
Winny
2

Asal tahu saja - Anda tidak terbatas pada satu perintah per |pipe:

this happens | then this | { then ; all of ; this too ; } | before this

Semua proses itu dipanggil pada saat yang sama - tetapi mereka semua menunggu |pipesebelum mereka sebelum benar-benar melakukan apa pun - asalkan mereka membaca |pipesama sekali, yaitu. Jadi, jika Anda perlu mengevaluasi variabel midstream, atau untuk mengatur pengalihan, Anda bisa. Santai saja.

echo "it takes time" |
{ exec 4>|file ; cat >&4 ; } |
( sleep 1 && cat <file )

it takes time

Ini cara lain:

echo "more of the same" |
( IFS= ; su -mc 'echo '"$(printf "'%s' " "`cat`")"' >|file' </dev/tty ) |
echo end of pipe

Jika Anda tidak melakukannya ( subshell ), perintahnya juga $(cat)akan </dev/ttyberhasil.

Tetapi jika Anda menggunakan dokumen-sini, Anda tidak perlu dua cats:

rm ./file
su -c 'cat <&3 >|./file; echo "middle here"' 3<<HERE >&2 | {\
    until [ -s ./file ] ; do sleep 1 ; done ;\
    sed 's/beginning/end/' ./file ; }
$(echo "this is the beginning" | sed 'a\of the pipeline' | tee /dev/stderr)
HERE

KELUARAN:

this is the beginning
of the pipeline
Password:
middle here
this is the end
of the pipeline

Sebagian besar di atas hanya untuk demo ini. Yang Anda butuhkan adalah:

su -c 'cat <&3 >./file' 3<<HERE | { wait as needed ; more stuff to do ; }
$(echo "something" | and other things)
HERE
mikeserv
sumber
Saya tahu itu. Itu sedikit atau tidak ada hubungannya dengan pertanyaan, atau jadi saya pikir. Tapi entah bagaimana itu membuat saya mendapat jawaban :) Lihat pertanyaan saya yang diperbarui.
x-yuri
@ x-yuri Anda masih bisa meletakkan dokumen di sini di tengah pipa. gema sesuatu | {su 'lakukan beberapa hal> /record.here'; } << DI SINI | akhir gema pipa \ n $ (cat) \ nHERE \ n
mikeserv
Memang, saya tidak berpikir menggunakan kucing di dalam dokumen di sini. Bagaimanapun, Anda tidak perlu mengelompokkan di sana.
x-yuri
@ x-yuri - itu tergantung pada apa yang ingin Anda lakukan dengannya. Anda dapat menggunakan salah satu atau keduanya. Saya hanya berusaha menunjukkan bahwa Anda memiliki opsi. Jawaban Patrick adalah yang benar di sini, ini hanyalah cara lain yang lebih berbelit-belit. Itu di sini-doc tidak kelompok, meskipun - itu kelompok kucing dalam sebuah subkulit.
mikeserv
Dengan pengelompokan yang saya maksud adalah kurung kurawal .
x-yuri