Setelah memutakhirkan ke versi rilis baru, bash
skrip saya mulai meludah kesalahan:
bash: /dev/stderr: Permission denied
dalam versi sebelumnya Bash akan mengenali secara internal nama-nama file tersebut (itulah sebabnya pertanyaan ini bukan duplikat dari yang ini ) dan melakukan hal yang benar (tm) , namun, ini telah berhenti berfungsi sekarang. Apa yang dapat saya lakukan untuk dapat menjalankan skrip saya lagi dengan sukses?
Saya telah mencoba menambahkan pengguna yang menjalankan skrip ke grup tty
, tetapi ini tidak ada bedanya (bahkan setelah logout dan kembali).
Saya dapat mereproduksi ini di baris perintah tanpa masalah:
$ echo test > /dev/stdout
bash: /dev/stdout: Permission denied
$ echo test > /dev/stderr
bash: /dev/stderr: Permission denied
$ ls -l /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stdout -> /proc/self/fd/1
$ ls -lL /dev/stdout /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stdout
$ echo $BASH_VERSION
4.2.24(1)-release
Pada sistem yang lebih lama (Ubuntu 10.04):
$ echo $BASH_VERSION
4.1.5(1)-release
bash
permissions
stdout
0xC0000022L
sumber
sumber
ls -l /dev/stdout /dev/stderr
danls -lL /dev/stdout /dev/stderr
?sudo su username2 -
...echo $BASH_VERSION
Jawaban:
Saya tidak berpikir ini sepenuhnya masalah bash.
Dalam komentar, Anda mengatakan bahwa Anda melihat kesalahan ini setelah melakukannya
saat masuk sebagai
username
. Itusu
yang memicu masalah./dev/stdout
adalah symlink ke/proc/self/fd/1
, yang merupakan symlink ke, misalnya/dev/pts/1
,./dev/pts/1
, Yang merupakan pseudoterminal sebuah, dimiliki oleh, dan ditulis oleh,username
; kepemilikan itu diberikan saatusername
masuk. Ketika Andasudo su username2
, kepemilikan/dev/pts/1
tidak berubah, danusername2
tidak memiliki izin menulis.Saya berpendapat bahwa ini adalah bug.
/dev/stdout
seharusnya , pada dasarnya, alias untuk aliran output standar, tetapi di sini kita melihat situasi di manaecho hello
berfungsi tetapiecho hello > /dev/stdout
gagal.Salah satu solusinya adalah dengan membuat
username2
anggota kelompoktty
, tetapi itu akan memberikanusername2
izin untuk menulis kepada anggota mana pun , yang mungkin tidak diinginkan.Solusi lain adalah login ke
username2
akun daripada menggunakansu
, sehingga/dev/stdout
menunjuk ke pseudoterminal yang baru dialokasikan milikusername2
. Ini mungkin tidak praktis.Solusi lain adalah dengan memodifikasi skrip Anda sehingga mereka tidak merujuk
/dev/stdout
dan/dev/stderr
; misalnya, ganti ini:dengan ini:
Saya melihat ini di sistem saya sendiri, Ubuntu 12.04, dengan bash 4.2.24 - meskipun dokumen bash (
info bash
) pada sistem saya mengatakan itu/dev/stdout
dan/dev/stderr
diperlakukan secara khusus ketika digunakan dalam pengalihan. Tetapi bahkan jika bash tidak memperlakukan nama-nama itu secara khusus, mereka harus tetap bertindak sebagai setara untuk stream I / O standar. (POSIX tidak menyebutkan/dev/std{in,out,err}
, jadi mungkin sulit untuk berpendapat bahwa ini adalah bug.)Melihat versi bash lama, dokumentasi menyiratkan bahwa
/dev/stdout
et al diperlakukan secara khusus apakah file ada atau tidak. Fitur ini diperkenalkan di bash 2.04, danNEWS
file untuk versi itu mengatakan:Tetapi jika Anda memeriksa kode sumber (
redir.c
), Anda akan melihat bahwa penanganan khusus diaktifkan hanya jika simbolHAVE_DEV_STDIN
didefinisikan (ini ditentukan ketika bash dibangun dari sumber).Sejauh yang saya tahu, tidak ada versi bash yang dirilis telah membuat penanganan khusus
/dev/stdout
tanpa syarat - kecuali beberapa distribusi telah menambalnya.Jadi solusi lain (yang belum saya coba) adalah untuk mengambil sumber bash , memodifikasi
redir.c
untuk membuat/dev/*
penanganan khusus tanpa syarat, dan menggunakan versi dibangun kembali Anda daripada yang datang dengan sistem Anda. Ini mungkin berlebihan, meskipun.RINGKASAN:
OS Anda, seperti milik saya, tidak menangani kepemilikan dan izin dari
/dev/stdout
dan/dev/stderr
dengan benar. bash seharusnya memperlakukan nama-nama ini secara khusus dalam pengalihan, tetapi pada kenyataannya ia melakukannya hanya jika file tidak ada. Itu tidak masalah jika/dev/stdout
dan/dev/stderr
bekerja dengan benar. Masalah ini hanya muncul ketika Andasu
ke akun lain atau melakukan sesuatu yang serupa; jika Anda cukup masuk ke akun, izinnya sudah benar.sumber
pam_ck_connector.so
untuk)./proc/self/fd/1
perizinannya diperbarui, tapi itu tidak ada gunanya, karena itu adalah symlink. Terjadi pada Fedora juga, yang tampaknya mengesampingkan ConsoleKit.Sebenarnya alasan untuk ini adalah bahwa udev secara khusus menetapkan izin untuk 0620 pada perangkat tty dan su tidak mengubah kepemilikan atau izin juga tidak seharusnya. Dalam pandangan saya ini membuat kita dalam situasi yang membuat / dev / std * non-portable.
Solusi sederhananya adalah dengan meletakkan "mesg y" di / etc / profile (atau profil tingkat atas apa pun yang ingin Anda gunakan) karena ini mengubah izin perangkat tty Anda ke 0622. Saya tidak begitu menyukainya tetapi mungkin lebih baik daripada mengubah aturan udev.
sumber
Sebagai pengguna Linux yang lama saya baru-baru ini membuat sistem Ubuntu 64 bit 12,04 LTS baru dan bingung mengapa skrip bash saya tidak berfungsi - izin ditolak - dan saya kemudian menemukan utas ini. Saya pikir masalahnya mungkin karena sesuatu di OS baru.
Pada akhirnya ternyata saya bodoh menggunakan alat UI untuk mengatur izin pada
/home
direktori saya , dan masalahnya terkait drive . Yang pasti, saya membuattemp
direktori/opt
dan menemukan skrip saya akan berjalan dengan baik dari sana. Setelah saya memperbaiki/home
izin drive semuanya kembali normal.Satu misteri kecil terpecahkan. mendesah
sumber
Ini adalah pertanyaan lama, tapi saya pikir masih sangat relevan, maka inilah solusi yang saya temukan yang tidak disebutkan di sini.
Saya menemukan pertanyaan ini karena saya juga telah melihat masalah dalam perintah eksekusi 'su' yang diaktifkan akun seperti ini di bash:
Karena semua yang saya coba lakukan adalah mengarahkan ulang stdout ke stderr, yang berikut ini mencapai hal yang sama, dan itu berfungsi bahkan dalam akun aktif su:
sumber