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

12

Il s'agit probablement d'un doublon, mais toutes mes recherches soulèvent des questions sur les erreurs d'autorisation refusée.

J'exécute 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 souhaite définir un mode d'autorisation de fichier spécifique si la redirection de sortie doit créer ce fichier. Existe-t-il un moyen de le faire avec une seule commande?

Par exemple, je pourrais essayer

foo >> /tmp/foo.log 0644

0644sont les autorisations avec lesquelles je veux me foo.logretrouver. La plupart des commandes que j'ai expérimentées dans bash finissent par être interprétées 0644comme un argument supplémentaire foo.

J'ai l'impression que cela va prendre une deuxième commande pour chmodles 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érées.

Patrick M
la source

Réponses:

5

Pour autant que je sache, il n'y a aucun moyen de le faire, 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
terdon
la source
Merci Slowki, c'était aussi mon intuition. Je vais le laisser ouvert pendant quelques jours, dans l'espoir d'attirer un gourou pour nous éclairer.
Patrick M
3
Le problème avec cette approche est qu'elle crée une fenêtre de temps courte lorsque les autorisations sur le fichier sont incorrectes. Je ne l'utiliserais pas si l'objectif est de protéger les données sensibles.
proski
1
Cette réponse fonctionne, dans la mesure où elle va, mais @proski a raison: les umaskréponses sont meilleures et l'une d'elles doit être acceptée.
Scott
15

Je sais que c'est une vieille question, mais je voulais ajouter mes deux cents.

J'ai eu la même idée et j'ai trouvé une solution similaire à BowlesCR . Le problème avec sa solution était que ma commande ( foo) ne fonctionnerait pas si je modifiais l'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, umaskaffecte uniquement la redirection vers foo.logdans le sous-shell. Tout le reste reste inchangé.

Un peu alambiqué, mais ça marche.

xynomorf
la source
Très agréable et efficace :) Ne peut tout simplement pas être utilisé avec la redirection stderr au-dessus du redir stdout.
Orsiris de Jong
5

Sans vrai script, vous pouvez enchaîner un peu:

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

Effectivement similaire à la réponse de Slowki , mais condensé en un seul revêtement.

La seule autre chose à laquelle je peux penser est de bricoler le umask. Il est préférable de le faire en sous-couche afin qu'il ne pollue pas l'environnement actuel:

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

Deux problèmes avec cela, cependant.

  1. Umask ne peut pas augmenter les autorisations au-dessus du niveau spécifié dans le creat()syscall (0666 semble être ce que Bash utilise).
  2. Cela ne changera pas les autorisations sur un fichier existant (car umasks'applique uniquement à la création de fichier ).
BowlesCR
la source
Je suis encore assez nouveau pour * nix que le umask est toujours un peu magique pour moi. Merci pour le conseil, je serai sûr de le lire.
Patrick M
Hmm… permet toujours à un processus non privilégié d'ouvrir le fichier et de lire plus tard son contenu.
Feuermurmel
(1) Félicitations pour avoir trouvé une utilisation intéressante et utile de cat. (Bien que cela ne suive pas le modèle standard des utilisations inutiles de cat.) (2) Je suppose que vous vouliez dire que bash utilise par  défaut le mode  0666 lors de la création de fichiers, et j'ai donc modifié votre réponse pour le dire. (Voir ça ,  ça   ... (suite)
Scott
(Suite)… et  ceci .) Et la question mentionne spécifiquement le mode 0644. Donc, une umaskvaleur de 22, 23 ou 32 fonctionnerait aussi, dans ce contexte (vous n'avez pas besoin d'utiliser un ou des zéro (s) en tête; quand les modes et les  umaskvaleurs sont spécifiés numériquement, ils sont toujours interprétés comme octaux).  22 est plus communément utilisé de façon conventionnelle.
Scott
@Feuermurmel: Et alors? La question appelle explicitement le mode 644. Nous devons supposer que l'OP sait que 644 signifie lisible par le monde et destiné à rendre ses informations publiques.
Scott
1

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 crois que vous pouvez utiliser quelque chose comme xynomorf a donné, et répondre à la préoccupation stderr d'Orsiris de Jong avec une légère modification pour utiliser la 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, utilisez umask 0077pour obtenir le mode 600 et interdire à tout autre utilisateur de voir le contenu.

piCookie
la source
0

Si vous souhaitez rediriger vers un script, contrairement umaskà la substitution de processus et installvous pouvez également définir le bit d'exécution:

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

<()place la sortie dans un fichier temporaire, voir Process-Substitution

laktak
la source