Comment décider que mv se déplace dans un répertoire plutôt que de remplacer le répertoire?

18

Disons que j'ai un répertoire /hello.

Alors je le fais mv /hello /hello2.

Est-ce que je déplaçais /helloen /hello2/hello? Ou suis - je déplaçais /helloà /hello2?

Il semble que lorsque je fais quelque chose comme ça, j'obtiens des résultats incohérents.

user4951
la source
1
Dans quel cas le résultat est-il incohérent? Il semble que chaque fois que le répertoire cible existe, il se déplace dans le répertoire cible, sinon il est renommé.
jmathew
C'est incohérent. La même commande devrait faire la même chose. Cela signifie que la commande est ambiguë.
user4951
Ce n'est pas vraiment incohérent, car il agit de manière cohérente dans le contexte. Bien que je puisse voir à quel point c'est déroutant, mais plus j'y pense, la commande doit être de cette façon afin de fonctionner pour tous les scénarios.
jmathew
Je dirais plutôt que c'est ainsi qu'il est conçu et son aussi logique .. si vous utilisez mvavec des fichiers, il fait la même chose.juste renaming.but mvavec les répertoires Ce n'est pas bon de supprimer tout le répertoire avec le sous-répertoire à cause d'une mvcommande qui n'est pas sûr. il est donc déplacé comme test1/test2. mais si vous voulez quand même l'atteindre, écrivez un aliasqui vérifie si le paramètre donné est répertoire et ensuite rm -rf le répertoire et utilise la mvcommande mais utilisez-le à vos risques et périls.
harish.venkat
Je soupçonne que votre exemple est basé sur un mauvais souvenir de quelque chose qui s'est produit dans le passé, basé sur "Il semble que je fais quelque chose comme ça". Si les deux /helloet /hello2sont des répertoires, j'ai remarqué que cp /hello /hello2c'est celui qui est incohérent. En fonction de la combinaison de barres obliques de fin, le contenu de /helloest parfois copié /hello2, et parfois le répertoire lui-même est copié.
Izkata

Réponses:

16

mv a btente de se déplacer adans bsi best un répertoire ou un lien symbolique vers un répertoire. Sinon, il sera renommé (ou copié et supprimé si sur différents systèmes de fichiers) aen b.

Pour obtenir un résultat cohérent pour déplacer un fichier dans un répertoire, vous pouvez faire:

mv file dir/

ou

mv file dir/.

Si dirn'existe pas, vous obtiendrez une erreur, et il ne sera pas renommer fileà dir.

Si, en revanche, vous voulez faire un renamesans avoir à vous soucier si le fichier de destination existe ou non en tant que répertoire, avec GNU mv, vous pouvez faire:

mv -T file dest

Dans ce cas, filene sera pas déplacé dans destsi destest un répertoire. Cependant, si les deux fileet destsont des répertoires et destsont vides, fileils seront renommés dest(et l'original sera destsupprimé). Si les deux sont des répertoires et destn'est pas vide, mv -Tse plaindra.

De même, si fileet nedest sont pas des répertoires (et cela inclut les liens symboliques, y compris les liens symboliques vers les répertoires), filesera renommé dest(bien que vous obtiendrez une invite si vous n'avez pas la permission d'écrire dest), et l'original destsera supprimé. Il y a une différence avec mv file destdans le cas où destest un lien symbolique vers un répertoire. Avec -T, fileest renommé en dest, mais sans -T, fileest déplacé dans le répertoire indiqué par dest.

Donc, pour résumer, après mv -T file dest, soit filesera renommé, destsoit vous obtiendrez un message d'erreur (ou une invite). Si la commande a réussi, l'original dest, s'il existait auparavant, aura été supprimé.

Stéphane Chazelas
la source
14

Cela dépend entièrement de la présence ou non d'un répertoire nommé '/ hello2'.

Si / hello2 existe ET est un répertoire, alors move déplacera toujours / hello vers / hello / hello2

Si / hello2 n'existe pas, alors move renommera toujours / hello en / hello2

Si / hello2 existe ET est un fichier, vous obtiendrez une erreur, "ne peut pas remplacer le non-répertoire 'hello2' par le répertoire 'hello'.

Don Simon
la source
3

J'ai essayé ces

mkdir test1
mv -v test1 test2
output:`test1' -> `test2'
mkdir test1
mv -v test2 test1
output: `test2' -> `test1/test2'
touch test2
output:mv: cannot overwrite non-directory `test2' with directory `test1'

j'espère que cela explique tout. -vest le mode verbeux.

harish.venkat
la source