Existe-t-il un moyen de dire à sudo de définir mon nom d'utilisateur comme propriétaire pour les fichiers créés au lieu de root?

19

Si je fais un sudo cp /etc/foo.txt ~/foo.txt, le nouveau fichier est créé avec rootcomme propriétaire.

Pour l'instant, je ne vois pas d'autre moyen que d'utiliser les deux dernières commandes ( lspour clarifier le cas d'utilisation):

belmin@server1$ ls /etc/foo.txt
>  -rw------- 1 root root 3848 Mar  6 20:35 /etc/foo.txt
>
belmin@server1$ sudo cp /etc/foo.txt ~/foo.txt
belmin@server1$ sudo chown belmin: $_

Je préférerais:

  1. Le faire en une seule sudocommande.
  2. Ne pas avoir à spécifier mon utilisateur actuel (peut-être en utilisant une variable?).
Belmin Fernandez
la source
sudo cat /etc/foo.txt > ~/foo.txt. Les fichiers ont tendance à être uniquement lisibles par root pour une raison, alors n'oubliez pas de garder cette raison à l'esprit lorsque vous faites des copies lisibles par des utilisateurs non root.
jw013

Réponses:

32

Utilisez installau lieu de cp:

sudo install -o belmin /etc/foo.txt ~/foo.txt
Jenny D
la source
N'était pas au courant install. Je vous remercie.
Belmin Fernandez
4
@BelminFernandez: Afin de tenir compte de votre deuxième préférence:sudo install -o "$USER" /etc/foo.txt ~/foo.txt
pause jusqu'à nouvel ordre.
14

Avec un compatible POSIXcp , vous pouvez sudo cp -p foo barpour préserver les métadonnées de fichier suivant lors de la copie:

  • Temps d'accès
  • Temps de modification
  • Identifiant d'utilisateur
  • ID de groupe
  • Mode

Si vous souhaitez définir un autre utilisateur, la solution de JennyD est la meilleure.

l0b0
la source
2
Cela ne fonctionne que lorsque le fichier d'origine appartient à l'utilisateur cible.
Jenny D
4
Je suppose que la personne qui exécute sudo ne possède pas le fichier d'origine, sinon elle n'aurait pas besoin d'utiliser sudo.
EightBitTony
@EightBitTony Vous n'avez pas besoin sudode copier un fichier que vous ne possédez pas. Vous avez juste besoin d'un accès en lecture , après tout.
l0b0
Oui, faute de frappe de ma part - mais je suppose que l'ID utilisateur en question ne peut pas non plus lire le fichier, car ils n'auraient toujours pas besoin de sudo. Nous devons donc supposer que l'ID utilisateur destiné à posséder le fichier final n'a pas accès au fichier d'origine. Quoi qu'il en soit, ce n'est pas un «problème» sudo. Votre réponse suggère que la préservation d'un propriétaire que nous devons supposer n'est pas souhaitée.
EightBitTony
2
Il est théoriquement possible que le fichier soit la propriété de l'utilisateur cible mais se trouve dans un répertoire dans lequel l'utilisateur cible n'est pas autorisé à entrer. Mais ce n'est pas très probable :-)
Jenny D
8

Si tu fais:

sudo cat /etc/foo.txt > ~/foo.txt

Ensuite, ~/foo.txtil sera ouvert par le shell pendant que vous (créé avec vos informations d'identification), puis sudosera exécuté avec sa sortie standard redirigée vers cela.

À la fin, le fichier vous appartiendra.

Ce type d'approche permet également de limiter les tâches effectuées par root. Ici, rootn'utilise que son privilège pour s'ouvrir /etc/foo.txt, il ne fait pas ce qui est potentiellement dangereux (ouvrir un fichier en écriture, cela pourrait avoir de mauvaises conséquences s'il ~/foo.txts'agissait d'un lien symbolique par exemple).

Stéphane Chazelas
la source
2
Cela suppose que l'utilisateur peut écrire dans le répertoire cible.
Johan
3

À l'aide de sudo, vous basculez vers un autre utilisateur. C'est tout l'intérêt de la commande. Je suppose que vous n'avez pas d'accès régulier au premier fichier, vous devez donc être un autre utilisateur ( rootdans ce cas) pour y accéder.

Il n'y a aucun moyen pour sudolui de gérer cela, car tout sudoce que vous faites est de vous basculer vers l'autre utilisateur pour exécuter la commande.

Tu devras

  1. continuer à utiliser deux commandes (ou une commande composée)
  2. trouver une autre commande (comme installer, vue dans une autre réponse)
  3. ou écrire un script et exécuter ce script via sudo.
EightBitTony
la source
1

Sudo crée une variable d'environnement "SUDO_USER" que vous pouvez utiliser pour trouver l'utilisateur qui s'est connecté (en fait, qui a exécuté Sudo).

En supposant que vous Sudo pour rooter (il est possible d'utiliser Sudo pour accéder à d'autres utilisateurs aussi), vous pouvez écrire un script pour automatiser les deux étapes suivantes.

cp source target
chown $SUDO_USER target

(Cela ne fonctionnera pas si vous faites un sudo à un utilisateur non root car seul root peut donner des fichiers.)

L'automatiser sera un peu de travail. Si la source est un fichier unique et la cible n'est pas un répertoire, alors votre travail est terminé. Je suppose que vous avez posé la question parce que le problème n'est un vrai problème que dans des situations plus complexes, par exemple lorsque vous faites quelque chose comme:

cp /path/source/some*files /path/target/directory/

Un script complexe pour déterminer quels fichiers et quels répertoires sont passés, lesquels étaient préexistants, lesquels ont été réellement remplacés et pour changer la propriété des seuls fichiers copiés avec succès pourrait être écrit.

Ce travail a déjà été fait. Vous pouvez utiliser cpio- Après sudo pour rooter, utilisez cpio pour copier les fichiers. cpio a besoin d'une liste des fichiers à copier, c'est donc un processus en deux étapes. Ci-dessous, j'utilise lspour générer la liste des fichiers à copier.

ls /path/source/some*files | cpio -pdm --owner $SUDO_USER /path/target/directory/

Le -pdmmoyen "Mode passthrough, Créer des répertoires selon les besoins, Maintenir les temps de modification des fichiers"

--owner $SUDO_USER" oblige l'utilisateur spécifié à posséder les fichiers.

L'opérande final est le répertoire où cpio doit stocker les fichiers.

Pour en savoir plus sur le caractère génial de cpio, consultez la page de manuel CPIO ici

Faire cela dans une seule commande sudo est également possible. En supposant que votre utilisateur dispose des droits d'accès aux fichiers, utilisez sudo uniquement pour la partie cpio, comme ceci:

ls /path/source/some*files | cpio -pdm --owner $USER /path/target/directory/

Dans le cas ci-dessus, j'utilise $ USER au lieu de $ SUDO_USER car il est évalué avant l'exécution de Sudo. Sinon, si l'utilisateur n'a pas accès à la liste des fichiers, placez-le dans un script d'encapsuleur et utilisez sudo pour exécuter l'encapsuleur. Cela peut devenir plus difficile, mais dans le cas le plus simple, l'encapsuleur prend deux arguments, une source et une cible.

Cela va dans le wrapper "cp_as_user":

ls $1 | cpio -pdm --owner $SUDO_USER $2

Ensuite, utilisez le wrapper comme ceci:

sudo cp_as_user "/ chemin / vers / certains * fichiers" / chemin / vers / cible / répertoire

Johan
la source