Como definir permissões de arquivo específicas ao redirecionar a saída?


12

Provavelmente é uma duplicata, mas todas as minhas pesquisas estão levantando perguntas sobre erros de permissão negada.

Estou executando um comando em um shell bash. Quero redirecionar a saída para anexar a um arquivo que provavelmente não existe na primeira execução. Eu quero definir o modo de permissões de arquivo específico se o redirecionamento de saída precisar criar esse arquivo. Existe uma maneira de fazer isso com um comando?

Por exemplo, eu posso tentar

foo >> /tmp/foo.log 0644

onde 0644estão as permissões que eu quero foo.logterminar. A maioria dos comandos que experimentei no bash acabam interpretando 0644como um argumento adicional para foo.

Tenho a sensação de que isso vai levar um segundo comando para chmodas permissões antes ou depois de gravá-lo.

Estou usando o GNU bash 4.2.25 e o Ubuntu 12.04, se isso faz diferença - respostas gerais são preferidas.

Respostas:


5

Não há como fazê-lo durante a canalização, tanto quanto eu sei, um script simples pode ser a melhor solução.

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

Obrigado Slowki, esse foi o meu palpite também. Vou deixar em aberto por alguns dias, na esperança de atrair um guru para nos esclarecer.
Patrick M

3
O problema com essa abordagem é que ela cria uma janela de tempo curta quando as permissões no arquivo estão incorretas. Eu não usaria se o objetivo é proteger dados confidenciais.
proski 14/10/2015

11
Essa resposta funciona, na medida do possível, mas o @proski está certo: as umaskrespostas são melhores e uma delas deve ser aceita.
Scott

15

Eu sei que é uma pergunta antiga, mas eu queria adicionar meus dois centavos.

Eu tive a mesma idéia e surgiu uma solução semelhante ao BowlesCR . O problema com a solução dele era que meu command ( foo) não funcionaria se eu alterasse o umask antes de executá-lo, então esta é a minha opinião sobre o problema:

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

Aqui, umaskafeta apenas o redirecionamento para foo.logno subshell. Tudo o resto permanece inalterado.

Um pouco complicado, mas funciona.


Muito bom e eficaz :) Só não pode ser usado com o redirecionamento stderr no topo do redirecionamento stdout.
Orsiris de Jong 8/17

5

Sem scripts verdadeiros, você pode encadear um pouco:

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

Efetivamente semelhante à resposta de Slowki , mas condensado em uma linha.

A única outra coisa que consigo pensar é mexer com o umask. É melhor fazer isso em um subshell para não poluir o ambiente atual:

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

Dois problemas com isso, no entanto.

  1. O Umask não pode aumentar as permissões acima do nível especificado no creat()syscall (0666 parece ser o que o Bash usa).
  2. Isso não altera as permissões em um arquivo existente (porque umaskse aplica apenas à criação do arquivo ).

Eu ainda sou novo o suficiente para * nix que o umask ainda é um pouco de mágica para mim. Obrigado pela dica, não deixe de ler.
Patrick M

Hmm ... Ainda permite que um processo sem privilégios abra o arquivo e depois leia seu conteúdo.
Feuermurmel

(1) Parabéns por encontrar um uso interessante e útil de cat. (Embora isso não siga o padrão de usos inúteis de  cat.) (2) Presumo que você quis dizer que o bash usa como padrão o modo  0666 ao criar arquivos e, por isso, editei sua resposta para dizer isso. (Veja isso ,  isso   ... (continua)
Scott

(Continua) ... e  isso .) E a pergunta menciona especificamente o modo 0644. Portanto, um umaskvalor de 22, 23 ou 32 também funcionaria nesse contexto (você não precisa usar zero (s) à esquerda; quando modos e  umaskvalores são especificados numericamente, eles sempre são interpretados como octais).  22 é mais comumente usado convencionalmente.
12763 Scott

@Feuermurmel: E daí? A pergunta exige explicitamente o modo 644. Temos que assumir que o OP sabe que 644 significa legível pelo mundo e pretende tornar suas informações públicas.
12763 Scott

1

Quando o redirecionamento define as permissões erradas, por exemplo:

$ 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

Eu acredito que você pode usar algo como o xynomorf forneceu e abordar a preocupação stderr da Orsiris de Jong com uma pequena modificação para usar a substituição do processo do 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

Naturalmente, use umask 0077para obter o modo 600 e proibir que outros usuários vejam o conteúdo.


0

Se você deseja redirecionar para um script, ao contrário umask, com substituição de processo e installtambém pode definir o bit de execução:

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

<()coloca a saída em um arquivo temporário, consulte Substituição de Processo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.