18 votes

Comment définir des autorisations spécifiques pour les fichiers lors de la redirection de la sortie ?

Il s'agit probablement d'un doublon, mais toutes mes recherches aboutissent à des questions sur les erreurs de refus d'autorisation.

Je lance une commande dans un Shell bash. Je veux rediriger la sortie pour l'ajouter à un fichier qui n'existe probablement pas lors de la première exécution. Je veux définir un mode de permissions spécifique pour le fichier si la redirection de la sortie doit créer ce fichier. Y a-t-il un moyen de faire cela avec une seule commande ?

Par exemple, je pourrais essayer

foo >> /tmp/foo.log 0644

donde 0644 sont les autorisations que je souhaite foo.log pour finir. La plupart des commandes que j'ai expérimentées dans bash finissent par interpréter 0644 comme argument supplémentaire à foo .

J'ai l'impression qu'il va falloir un deuxième commandement pour chmod les autorisations avant ou après y avoir écrit.

J'utilise GNU bash 4.2.25 et Ubuntu 12.04, si cela fait une différence - les réponses générales sont préférables.

17voto

xynomorf Points 171

Je sais que c'est une vieille question, mais je voulais ajouter mon grain de sel.

J'ai eu la même idée et j'ai trouvé une solution similaire à la suivante BowlesCR . Le problème de cette solution est que ma commande ( foo ) ne fonctionnerait pas si je changeais le umask avant de l'exécuter, c'est donc mon point de vue sur le problème :

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

Ici, umask n'affecte que la redirection vers foo.log dans la sous-coquille. Tout le reste n'est pas affecté.

C'est un peu compliqué, mais ça marche.

6voto

Il n'y a pas de moyen de le faire en pipant pour autant que je sache, un simple script pourrait être la meilleure solution.

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

6voto

Matthew Frederick Points 14932

Sans véritable script, il est possible d'enchaîner un peu :

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

Effectivement similaire à Réponse de Slowki mais condensée en une phrase.

La seule autre chose à laquelle je peux penser est de bricoler avec l'umask. Le mieux est de le faire dans un sous-shell pour ne pas polluer l'environnement actuel :

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

Deux problèmes se posent cependant.

  1. Umask ne peut pas augmenter les permissions au-delà du niveau spécifié dans l'option creat() syscall (0666 semble être la valeur utilisée par Bash).
  2. Cela ne modifiera pas les autorisations d'un fichier existant (parce que umask ne s'applique qu'au fichier création ).

1voto

Kets Points 125

Lorsque la redirection définit les mauvaises autorisations, par exemple :

$ 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

Je pense que vous pouvez utiliser quelque chose comme ce que xynomorf a donné, et répondre à la préoccupation stderr d'Orsiris de Jong avec une légère modification pour utiliser l'option substitution de processus 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

Naturellement, utiliser umask 0077 pour obtenir le mode 600 et interdire à tout autre utilisateur d'en voir le contenu.

0voto

laktak Points 2421

Si vous souhaitez rediriger vers un script, à la différence de umask avec substitution de processus et install vous pouvez également activer le bit d'exécution :

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

<() place la sortie dans un fichier temporaire, voir Processus de substitution

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X