これが完全にbashの問題だとは思わない。
コメントで、あなたはこの後にこのエラーを見たと言った
sudo su username2
としてログインしたときusername。それsuが問題を引き起こしているのです。
/dev/stdoutはへのシンボリックリンクです/proc/self/fd/1。これは、などへのシンボリックリンク/dev/pts/1です。/dev/pts/1、これは擬似端末であり、所有者であり、書き込み可能ですusername。usernameログインすると、その所有権が付与されます。の場合sudo su username2、の所有権は/dev/pts/1変更されusername2ず、書き込み権限もありません。
これはバグだと主張します。 実際には、標準出力ストリームのエイリアスである/dev/stdout 必要がありますが、ここではecho hello機能するがecho hello > /dev/stdout失敗する状況を確認します。
回避策の1つusername2は、groupのメンバーを作成することですが、これにより任意の tty への書き込み許可ttyが与えusername2られますが、これはおそらく望ましくありません。
別の回避策は、username2使用するよりむしろアカウントにログインすることですsu、それが/dev/stdout所有する新しく割り当てられた擬似端末を指すようにusername2。これは実用的ではないかもしれません。
彼らはを参照していないので、別の回避策は、あなたのスクリプトを変更することであろう/dev/stdoutと/dev/stderr。たとえば、これを置き換えます:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
これで:
echo OUT
echo ERR 1>&2
私はbashの4.2.24で、私自身のシステムは、Ubuntu 12.04でこれを見る- bashのドキュメント(にもかかわらず、info bash私のシステムでは)と言う/dev/stdoutと、/dev/stderrリダイレクトに使用された場合、特別に扱われます。ただし、bashがこれらの名前を特別に扱わない場合でも、標準のI / Oストリームの同等物として機能する必要があります。(POSIXはに言及していない/dev/std{in,out,err}ので、これがバグであると主張するのは難しいかもしれません。)
古いバージョンのbashを見ると、ドキュメント/dev/stdoutは、ファイルが存在するかどうかにかかわらず、et alなどが特別に扱われることを示唆しています。この機能はbash 2.04で導入されNEWS、そのバージョンのファイルには次のように記載されています。
リダイレクトコードは、ファイルシステムに存在するかどうかに関係なく、/ dev / fd / N、/ dev / stdin、/ dev / stdout、および/ dev / stderrといういくつかのファイル名を特別に処理するようになりました。
しかし、ソースコード(redir.c)を調べると、シンボルが定義されている場合にのみ特別な処理が有効になっていることがわかりますHAVE_DEV_STDIN(これは、bashがソースからビルドされるときに決定されます)。
私の知る限り、リリースされたバージョンのbashは、他のディストリビューションがパッチを適用しない限り、他の特別な処理を無条件にしませんでし/dev/stdoutた。
したがって、別の回避策(私は試していません)は、bashソースを取得し、変更することですredir.c、特別な/dev/*処理が無条件になるようし、システムに付属しているバージョンではなく、再構築したバージョンを使用します。ただし、これはおそらく過剰です。
要約:
お使いのOSは、鉱山のような、の所有権とアクセス権を処理していない/dev/stdoutと/dev/stderr、正しく。bashはおそらくリダイレクトに特別にこれらの名前を扱いますが、ファイルが存在しない場合にのみ、実際にはそう。それは問題ではなく/dev/stdout、/dev/stderr正しく動作します。この問題はsu、別のアカウントにアクセスするか、同様のことを行う場合にのみ発生します。アカウントに単純にログインする場合、権限は正しいです。
ls -l /dev/stdout /dev/stderrand の出力は何ls -lL /dev/stdout /dev/stderrですか?