Bunun tamamen bir bash sorunu olduğunu düşünmüyorum .
Bir yorumda, bu hatayı yaptıktan sonra gördüğünüzü söylediniz
sudo su username2
olarak giriş yaptığınızda username. Bu var susorunu tetikleyen söyledi.
/dev/stdoutiçin bir sembolik /proc/self/fd/1bağlantıdır, örneğin bir sembolik bağlantıdır /dev/pts/1. /dev/pts/1sözde bir yalancı olan, ait olduğu ve yazılabilir olduğu username; bu sahiplik, usernameoturum açıldığında verildi . Siz sudo su username2, sahipliğinin /dev/pts/1değişmediği ve username2yazma izniniz olmadığı zaman.
Bunun bir hata olduğunu iddia ediyorum. gerçekte standart çıktı akışı için bir takma ad /dev/stdout olmalıdır , ancak burada echo helloişe yarayan ancak echo hello > /dev/stdoutbaşarısız olan bir durum görüyoruz .
Geçici çözümlerden biri username2, grubun bir üyesi olmak olabilir tty, ancak bu istenmeyen bir durum olan herhangi bir tty'ye username2yazma izni verir .
Başka bir geçici çözüm, username2kullanmak yerine hesaba giriş yapmaktır su, böylece /dev/stdoutyeni tahsis edilen bir sahte sözde işaret eder username2. Bu pratik olmayabilir.
Başka bir geçici çözüm onlar atıfta kalmamak senaryolarınızı değiştirmek olacaktır /dev/stdoutve /dev/stderr; örneğin, şunu değiştirin:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
bundan:
echo OUT
echo ERR 1>&2
Bunu kendi sistemimde, Ubuntu 12.04, bash 4.2.24 ile görüyorum - sistemimdeki bash belgesi ( info bash) bunu söylüyor /dev/stdoutve /dev/stderryönlendirmelerde kullanıldığında özel olarak ele alınıyor . Ancak bash bu isimleri özel olarak ele almasa bile, yine de standart G / Ç akışları için eşdeğer olarak hareket etmelidirler. (POSIX bundan bahsetmez /dev/std{in,out,err}, bu yüzden bunun bir hata olduğunu iddia etmek zor olabilir.)
Bash'in eski sürümlerine bakıldığında, belgeler /dev/stdoutet al'ın dosyalar olsun veya olmasın özel olarak ele alındığını ima eder . Özellik bash 2.04'te tanıtıldı ve NEWSbu sürümün dosyası şöyle diyor:
Yeniden yönlendirme kodu artık birkaç dosya adını özellikle işliyor: / dev / fd / N, / dev / stdin, / dev / stdout ve / dev / stderr, dosya sisteminde bulunup bulunmadığına bakılmaksızın.
Ancak kaynak kodunu ( redir.c) incelerseniz, özel işlemin yalnızca sembol HAVE_DEV_STDINtanımlandığında etkinleştirildiğini görürsünüz (bu, bash kaynağından oluşturulduğunda belirlenir).
Söyleyebildiğim kadarıyla , bash'ın yayınlanmış hiçbir sürümü /dev/stdoutet al'ın özel işlemesini koşulsuz hale getirmedi - bazı dağıtımlar yama yapmadıysa.
Bu yüzden (denemediğim) başka bir geçici çözüm bash kaynaklarını kapmak redir.c, özel /dev/*işlemeyi koşulsuz yapmak için değiştirmek ve sisteminizle birlikte gelenlerden ziyade yeniden oluşturulmuş sürümünüzü kullanmak olacaktır. Yine de, bu muhtemelen aşırıdır.
ÖZET:
İşletim sisteminiz, benimki gibi, sahipliğini ve izinlerini doğru /dev/stdoutve /dev/stderrdoğru işlemiyor. bash sözde bu isimleri yönlendirmelerde özel olarak ele alır, ancak aslında sadece dosyalar yoksa yapar. Eğer bunun bir önemi olmaz /dev/stdoutve /dev/stderrdoğru çalıştı. Bu sorun yalnızca subaşka bir hesaba gittiğinizde veya benzer bir şey yaptığınızda ortaya çıkar; bir hesapta oturum açarsanız, izinler doğrudur.
ls -l /dev/stdout /dev/stderrvels -lL /dev/stdout /dev/stderr?