Apakah ada cara untuk memberitahu sudo untuk menetapkan nama pengguna saya sebagai pemilik untuk file yang dibuat alih-alih root?

19

Jika saya melakukan sudo cp /etc/foo.txt ~/foo.txt, file baru dibuat dengan rootsebagai pemilik.

Saat ini, saya tidak menemukan jalan keluar selain menggunakan dua perintah terakhir ( lsuntuk mengklarifikasi kasus penggunaan):

belmin@server1$ ls /etc/foo.txt
>  -rw------- 1 root root 3848 Mar  6 20:35 /etc/foo.txt
>
belmin@server1$ sudo cp /etc/foo.txt ~/foo.txt
belmin@server1$ sudo chown belmin: $_

Saya akan lebih memilih:

  1. Melakukannya dalam satu sudoperintah.
  2. Tidak harus menentukan pengguna saya saat ini (mungkin menggunakan variabel?).
Belmin Fernandez
sumber
sudo cat /etc/foo.txt > ~/foo.txt. File cenderung hanya dapat dibaca oleh root karena suatu alasan, jadi ingatlah untuk mengingatnya ketika membuat salinan dapat dibaca oleh pengguna non-root.
jw013

Jawaban:

32

Gunakan installsebagai ganti cp:

sudo install -o belmin /etc/foo.txt ~/foo.txt
Jenny D
sumber
Tidak menyadarinya install. Terima kasih.
Belmin Fernandez
4
@BelminFernandez: Untuk mengakomodasi preferensi kedua Anda:sudo install -o "$USER" /etc/foo.txt ~/foo.txt
Dijeda sampai pemberitahuan lebih lanjut.
14

Dengan POSIX-kompatibelcp Anda bisa sudo cp -p foo baruntuk melestarikan metadata berkas berikut saat menyalin:

  • Waktu akses
  • Waktu modifikasi
  • identitas pengguna
  • ID grup
  • Mode

Jika Anda ingin menetapkan pengguna yang berbeda , solusi JennyD adalah yang terbaik.

l0b0
sumber
2
Itu hanya berfungsi ketika file asli dimiliki oleh pengguna target.
Jenny D
4
Saya kira orang yang menjalankan sudo tidak memiliki file asli, jika tidak mereka tidak perlu menggunakan sudo.
EightBitTony
@EightBitTony Anda tidak perlu sudomenyalin file yang bukan milik Anda. Anda hanya perlu akses baca .
l0b0
Ya, salah ketik pada bagian saya - tetapi saya menganggap ID pengguna yang bersangkutan tidak dapat membaca file juga, karena mereka masih tidak memerlukan sudo. Jadi kita harus mengasumsikan ID pengguna yang dimaksudkan untuk memiliki file akhir tidak memiliki akses ke file asli. Either way, ini bukan 'masalah' sudo. Jawaban Anda menyarankan untuk mempertahankan pemilik yang harus kami asumsikan tidak diinginkan.
EightBitTony
2
Secara teori dimungkinkan bahwa file tersebut dimiliki oleh pengguna target tetapi terletak di direktori di mana pengguna target tidak memiliki izin untuk masuk. Tapi itu tidak terlalu mungkin :-)
Jenny D
8

Jika kamu melakukan:

sudo cat /etc/foo.txt > ~/foo.txt

Kemudian ~/foo.txtakan terbuka oleh shell saat Anda (jadi dibuat dengan kredensial Anda), dan kemudian sudoakan dieksekusi dengan stdout yang diarahkan ke itu.

Pada akhirnya, file tersebut akan menjadi milik Anda.

Pendekatan semacam itu juga membantu membatasi hal-hal yang dilakukan oleh root. Di sini, roothanya menggunakan hak istimewanya untuk membuka /etc/foo.txt, itu tidak melakukan hal yang berpotensi berbahaya (membuka file untuk menulis, yang dapat memiliki konsekuensi buruk jika ~/foo.txtmisalnya symlink).

Stéphane Chazelas
sumber
2
Ini mengasumsikan pengguna dapat menulis ke direktori target.
Johan
3

Dengan menggunakan sudo, Anda beralih ke pengguna lain. Itulah inti dari perintah. Saya berasumsi Anda tidak memiliki akses reguler ke file pertama, jadi Anda harus menjadi pengguna lain ( rootdalam hal ini) untuk mendapatkan akses.

Tidak ada cara bagi sudodirinya untuk mengelola itu, karena semua sudoyang dilakukan adalah mengalihkan Anda ke pengguna lain untuk menjalankan perintah.

Kamu akan membutuhkan

  1. tetap menggunakan dua perintah (atau satu perintah majemuk)
  2. temukan perintah lain (seperti instal, lihat jawaban lain)
  3. atau menulis skrip dan menjalankan skrip itu melalui sudo.
EightBitTony
sumber
1

Sudo membuat variabel lingkungan "SUDO_USER" yang dapat Anda gunakan untuk mencari tahu pengguna yang masuk (sebenarnya siapa yang menjalankan Sudo).

Dengan asumsi Anda melakukan Sudo untuk melakukan rooting (Anda juga dapat menggunakan Sudo untuk mengakses pengguna lain), Anda dapat menulis skrip untuk mengotomatiskan dua langkah berikut.

cp source target
chown $SUDO_USER target

(Ini tidak akan berfungsi jika Anda sudo ke pengguna non root karena hanya root yang dapat memberikan file.)

Mengotomatiskannya akan sedikit bekerja. Jika sumber adalah file tunggal dan target bukan direktori, maka pekerjaan Anda selesai. Saya berasumsi bahwa Anda mengajukan pertanyaan karena masalahnya hanya masalah nyata dalam situasi yang lebih kompleks, misalnya ketika melakukan sesuatu seperti:

cp /path/source/some*files /path/target/directory/

Sebuah skrip yang rumit untuk mencari tahu file apa dan direktori apa yang dilewati, mana yang sudah ada sebelumnya, mana yang sebenarnya ditimpa, dan untuk mengubah kepemilikan hanya file yang berhasil disalin yang dapat ditulis.

Pekerjaan ini sudah dilakukan. Anda dapat menggunakan cpio- Setelah sudo untuk melakukan rooting, gunakan cpio untuk menyalin file. cpio memerlukan daftar file yang akan disalin sehingga ini adalah proses dua langkah. Di bawah ini saya gunakan lsuntuk menghasilkan daftar file yang akan disalin.

ls /path/source/some*files | cpio -pdm --owner $SUDO_USER /path/target/directory/

The -pdmberarti "mode passthrough, Buat direktori yang diperlukan, Menjaga kali modifikasi file"

--owner $SUDO_USER" menyebabkan pengguna yang ditentukan memiliki file.

Operan terakhir adalah direktori di mana cpio harus menyimpan file.

Untuk mempelajari lebih lanjut tentang kehebatan cpio, buka halaman manual CPIO di sini

Melakukan ini dalam satu perintah sudo juga dimungkinkan. Dengan asumsi bahwa pengguna Anda memiliki hak untuk mengakses file, gunakan sudo hanya untuk bagian cpio, seperti ini:

ls /path/source/some*files | cpio -pdm --owner $USER /path/target/directory/

Dalam kasus di atas saya menggunakan $ USER sebagai pengganti $ SUDO_USER karena dievaluasi sebelum Sudo berjalan. Atau, jika pengguna tidak memiliki akses untuk membuat daftar file, masukkan ke dalam skrip wrapper dan gunakan sudo untuk menjalankan wrapper. Ini bisa menjadi lebih sulit, tetapi dalam kasus yang paling sederhana Pembungkus membutuhkan dua argumen, satu sumber dan satu sasaran.

Ini masuk ke bungkus "cp_as_user":

ls $1 | cpio -pdm --owner $SUDO_USER $2

Kemudian gunakan pembungkus seperti ini:

sudo cp_as_user "/ path / ke / beberapa * file" / path / ke / target / direktori

Johan
sumber