出力をリダイレクトするときに特定のファイル権限を設定するにはどうすればよいですか?


12

これはおそらく重複していますが、すべての検索で、アクセス拒否エラーに関する質問が出ています。

bashシェルでコマンドを実行しています。出力をリダイレクトして、最初の実行時におそらく存在しないファイルに追加したいと思います。出力リダイレクトでこのファイルを作成する必要がある場合は、特定のファイルアクセス許可モードを設定します。1つのコマンドでこれを行う方法はありますか?

たとえば、私は試すかもしれません

foo >> /tmp/foo.log 0644

最終的0644に必要なアクセス許可はどこにありますかfoo.log。私がbashで実験したほとんどのコマンドは0644、への追加の引数として解釈されfooます。

これによりchmod、書き込みの前または後に、アクセス許可に対して2番目のコマンドが実行されるように感じます。

私はGNU bash 4.2.25とUbuntu 12.04を使用していますが、それが違いを生むのであれば、一般的な答えが優先されます。

回答:


5

私の知る限り、パイプ処理中にそれを行う方法はありません。単純なスクリプトが最善の解決策かもしれません。

if [ -e /tmp/foo.log ]; then
    foo >> /tmp/foo.log
else
    foo >> /tmp/foo.log
    chmod 0644 /tmp/foo.log
fi

Slowkiに感謝します。それも私の直感でした。グルを集めて私たちを啓蒙することを期待して、私はそれを数日間開いたままにします。
Patrick M

3
このアプローチの問題は、ファイルのアクセス許可が間違っている場合に、短時間のウィンドウが作成されることです。機密データを保護することが目的の場合は使用しません。
プロスキー2015年

1
この回答は機能しますが、@ proskiは正しいです。umask回答の方が優れており、そのうちの1つを受け入れる必要があります。
Scott

15

私はそれが古い質問であることを知っていますが、私の2セントを追加したかったのです。

私は同じ考えを持っていて、BowlesCRに似たソリューションを考え出しました。彼の解決策の問題は、foo実行する前にumaskを変更するとコマンド()が機能しなくなることでした。これが問題の私の見解です。

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

ここでは、サブシェルでのumaskリダイレクトのみに影響しfoo.logます。それ以外は影響を受けません。

少し複雑ですが、機能します。


非常に素晴らしく、効果的です:) stdout redirの上でのstderrリダイレクトでは使用できません。
Orsiris de Jong 2017

5

本当のスクリプトがなければ、少し連鎖できます:

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

Slowkiの回答に効果的に似ていますが、ワンライナーに凝縮されています。

他に考えられる唯一のことは、umaskをいじくり回すことです。現在の環境を汚染しないように、サブシェルでこれを行うのが最善です。

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

ただし、それには2つの問題があります。

  1. umaskは、creat()syscallで指定されたレベル(0666はBashが使用しているように見える)を超える権限を上げることはできません。
  2. これは既存のファイルのアクセス許可を変更しません(umaskファイルの作成にのみ適用されるため)。

私はまだ十分に新しいので、umaskはまだ少し魔法のようです。ヒントをありがとう、私はそれについて必ず読んでいきます。
Patrick M

Hmm…権限のないプロセスがファイルを開いて、後でその内容を読み取ることを許可します。
Feuermurmel

(1)おもしろくて便利なの使い方を見つけて、おめでとうございますcat。(これは、の無用な使用の標準的なパターンには従いません  cat。)(2)ファイルを作成するとき、bashはデフォルトでモード  0666になると言っていたと思います。そのため、あなたの答えを編集しました。(これを、  これを   …(続き)
Scott

(続き)…そして  これ。)そして質問は特にモード0644について言及しています。したがって、umaskこのコンテキストでは22、23または32の値も機能します(先行ゼロを使用する必要はありません)。モードと  umask値は数値で指定され、常に8進数として解釈されます)。  22 より一般的には、従来から使用されています。
スコット

@Feuermurmel:だから何?質問では、モード644を明示的に要求します。OPは、644が世界中で読み取り可能であり、情報を公開することを意図していることを知っていると想定する必要があります。
スコット

1

リダイレクトが誤った許可を設定する場合、例えば:

$ 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

私はあなたがxynomorfのようなものを使用でき、Orsiris de Jongからのstderrの懸念に対処し、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

当然、を使用umask 0077してモードを取得し600 、他のユーザーがコンテンツを見るのを禁止します。


0

とは異なりumask、プロセス置換を使用してスクリプトにリダイレクトするinstall場合は、実行ビットを設定することもできます。

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

<()出力を一時ファイルに配置します。プロセス置換を参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.