Bagaimana cara mengatur izin file tertentu saat mengarahkan output?

12

Ini mungkin duplikat, tetapi semua pencarian saya memunculkan pertanyaan tentang kesalahan izin ditolak.

Saya menjalankan perintah dalam bash shell. Saya ingin mengarahkan output untuk menambahkan ke file yang mungkin tidak ada pada jalankan pertama. Saya ingin mengatur mode izin file tertentu jika redirection output harus membuat file ini. Apakah ada cara untuk melakukan ini dengan satu perintah?

Sebagai contoh, saya mungkin mencoba

foo >> /tmp/foo.log 0644

di mana 0644izin yang ingin saya sampaikan foo.log. Kebanyakan perintah yang saya coba dalam bash akhirnya menafsirkan 0644sebagai argumen tambahan foo.

Saya merasa bahwa ini akan mengambil perintah kedua untuk chmodizin sebelum atau sesudah menulis untuk itu.

Saya menggunakan GNU bash 4.2.25 dan Ubuntu 12.04, jika itu membuat perbedaan - jawaban umum lebih disukai.

Patrick M
sumber

Jawaban:

5

Tidak ada cara untuk melakukannya sambil memipis sejauh yang saya tahu, skrip sederhana mungkin merupakan solusi terbaik.

if [ -e /tmp/foo.log ]; then
    foo >> /tmp/foo.log
else
    foo >> /tmp/foo.log
    chmod 0644 /tmp/foo.log
fi
terdon
sumber
Terima kasih Slowki, itu dugaan saya juga. Saya akan membiarkannya terbuka selama beberapa hari, dengan harapan menarik seorang guru untuk menerangi kita.
Patrick M
3
Masalah dengan pendekatan ini adalah bahwa ia menciptakan jendela waktu singkat ketika izin pada file tersebut salah. Saya tidak akan menggunakannya jika tujuannya adalah untuk melindungi data sensitif.
proski
1
Jawaban ini berfungsi, sejauh kelanjutannya, tetapi @proski benar: umaskjawabannya lebih baik, dan salah satunya harus diterima.
Scott
15

Saya tahu ini pertanyaan lama, tetapi saya ingin menambahkan dua sen saya.

Saya memiliki ide yang sama dan muncul dengan solusi yang mirip dengan BowlesCR . Masalah dengan solusinya adalah bahwa perintah saya ( foo) tidak akan berfungsi jika saya mengubah umask sebelum menjalankannya, jadi inilah pendapat saya tentang masalahnya:

foo | ( umask 0033; cat >> /tmp/foo.log; )

Di sini, umaskhanya memengaruhi pengalihan ke foo.logdalam subkulit. Segala sesuatu yang lain tetap tidak terpengaruh.

Sedikit berbelit-belit, tetapi berhasil.

xynomorf
sumber
Sangat bagus dan efektif :) Tidak dapat digunakan dengan pengalihan stderr di atas stdout redir.
Orsiris de Jong
5

Tanpa skrip yang benar, Anda dapat sedikit berantai:

touch /tmp/foo.log; chmod 0644 /tmp/foo.log; foo >> /tmp/foo.log

Secara efektif mirip dengan jawaban Slowki , tetapi terkondensasi menjadi satu-liner.

Satu-satunya hal lain yang bisa saya pikirkan adalah bermain-main dengan umask. Yang terbaik untuk melakukan ini dalam subkulit sehingga tidak mencemari lingkungan saat ini:

(umask 0033 && foo >> /tmp/foo.log)

Tapi ada dua masalah dengan itu.

  1. Umask tidak dapat meningkatkan izin di atas level yang ditentukan dalam creat()syscall (0666 tampaknya seperti yang digunakan Bash).
  2. Ini tidak akan mengubah izin pada file yang ada (karena umaskhanya berlaku untuk pembuatan file ).
BowlesCR
sumber
Saya masih cukup baru untuk * mengetahui bahwa umask masih sedikit ajaib bagi saya. Terima kasih atas tipnya, saya pasti akan membacanya.
Patrick M
Hmm ... Masih memungkinkan proses tidakrivil dari membuka file dan kemudian membaca kontennya.
Feuermurmel
(1) Selamat atas penemuan penggunaan yang menarik dan bermanfaat dari cat. (Meskipun ini tidak mengikuti pola standar penggunaan yang tidak berguna dari  cat.) (2) Saya menganggap Anda bermaksud mengatakan bahwa bash default ke mode  0666 saat membuat file, jadi saya mengedit jawaban Anda untuk mengatakannya. (Lihat ini ,  ini   ... (Lanjutkan)
Scott
(Lanjut) ... dan  ini .) Dan pertanyaannya secara spesifik menyebutkan mode 0644. Jadi umasknilai 22, 23 atau 32 akan bekerja dengan baik, dalam konteks ini (Anda tidak perlu menggunakan nol di depan; ketika mode dan  umasknilai ditentukan secara numerik, mereka selalu diartikan sebagai oktal).  22 lebih umum, digunakan secara konvensional.
Scott
@Feuermurmel: Jadi apa? Pertanyaannya secara eksplisit meminta mode 644. Kita harus berasumsi bahwa OP tahu bahwa 644 berarti dapat dibaca dunia dan dimaksudkan untuk membuat informasinya terbuka untuk umum.
Scott
1

Saat pengalihan menetapkan izin yang salah, misal:

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ ls -l capture.*
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDERR
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDOUT
$ cat capture.*
215 STDERR
216 STDERR
215 STDOUT
216 STDOUT

Saya percaya Anda dapat menggunakan sesuatu seperti xynomorf berikan, dan mengatasi masalah stderr dari Orsiris de Jong dengan sedikit modifikasi untuk menggunakan substitusi proses bash .

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ ls -l capture.*
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDERR
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDOUT
$ cat capture.*
233 STDERR text
238 STDERR text
233 STDOUT text
238 STDOUT text

Secara alami, gunakan umask 0077untuk mendapatkan mode 600 dan melarang pengguna lain melihat konten.

piCookie
sumber
0

Jika Anda ingin mengarahkan ulang ke skrip, tidak seperti umask, dengan substitusi proses dan installAnda juga dapat mengatur bit eksekusi:

install -m 755 <(echo commands go here) newscript

<()menempatkan output ke dalam file sementara, lihat Substitusi Proses

laktak
sumber