Bash: rediriger vers un fichier, toujours en créer de nouveaux

8

En bash, un lien de commande

echo test > actual.txt

remplacera le contenu du fichier appelé actual.txtpar "test" et créera le fichier s'il n'existe pas. Cependant, si le fichier existe, bash l'ouvrira, le tronquera et écrira le nouveau contenu dans le fichier.

Plus précisément, la commande de redirection échoue dans ce scénario:

ln -s /some/illegal/path link.txt
echo test > link.txt

Bash 4.4.12 me donne le message d'erreur déroutant link.txt: No such file or directory.

Pour éviter cela, assurez-vous de supprimer le fichier avant d'exécuter la commande redirigée.

rm link.txt && echo test > link.txt

Je me demandais, cependant, s'il y avait un ajustement des options bash ou de l'opérateur de redirection qui empêcherait ce mode d'échec. Des idées?

itsadok
la source
Que se passe-t-il si link.txtest un lien vers /dir/fileoù se /dirtrouve un fichier de type répertoire dans lequel vous disposez des droits d'écriture et de recherche, mais qui /dir/filen'existe pas (et la redirection le créerait sans message d'erreur)? Qu'en est-il s'il /dir/fileexiste mais n'est pas un fichier normal (périphérique, fifo, répertoire ...), ou si vous n'avez pas l'autorisation d'écrire ou de rechercher /dir?
Stéphane Chazelas

Réponses:

7

Essayer d'écrire sur un lien symbolique mort équivaut à essayer d'écrire sur un chemin qui n'existe pas. Il n'y a aucun moyen de "modifier" la redirection de sortie pour créer le chemin d'accès (y compris les répertoires intermédiaires) bash, et il n'y a aucune option de shell bashqui rend cela automatique.

Si le chemin intermédiaire existe, mais que le point final du lien n'existe pas, il sera créé par la redirection.

Vous pouvez faire quelque chose comme

if [ -h file ] && [ ! -f file ]; then
    rm file
fi

pour tester si "fichier" est un lien symbolique ( -h) et s'il fait référence à un fichier standard qui existe ( -f). S'il s'agit d'un lien symbolique mais ne fait pas référence à un fichier, vous le supprimez.

Kusalananda
la source
1
Le point de ma question était que je ne suis pas en train d'écrire à quoi que ce soit. Je veux créer un nouveau fichier appelé link.txt, et il se trouve qu'il y a un lien symbolique au même endroit. Pour mettre cela sous la forme d'une question: pourquoi s'embêter avec le test si je vais écraser le fichier sur la ligne suivante? Je peux juste le faire rm -fet cela aura le même effet.
itsadok
3
@itsadok Ah. Oui. Faire juste rm -f filenameavant d'y écrire avec la redirection résoudrait également votre problème. Mais cela dépend aussi si vous souhaitez qu'il soit dans le répertoire courant ou dans le répertoire où se trouve le point de fin du lien symbolique.
Kusalananda
Il se peut que vous ne disposiez toujours pas des autorisations d'accès au rmfichier ou d'écriture. Comme dans de nombreux cas, vous ne pouvez pas tout préparer. Vous devez évaluer les cas auxquels vous vous attendez vraiment (même en de rares occasions) et donc les traiter, quels cas vous considérez si peu probables que vous ne les traitez pas délibérément, et accepter qu'il y aura un certain nombre de cas que vous ne considérez pas et ne peut donc pas gérer.
Alfe