GNU/Linux >> Tutoriels Linux >  >> Ubuntu

Sh Alternative à Bash Cp {fichier, fichier} ?

Dans un script, si je mets #!/bin/bash en haut, cela fonctionnera bien :

cp directory/{foo,bar} destination

Cependant, avec sh, cela donnera l'erreur "aucun fichier ou répertoire de ce type". Dans sh, existe-t-il un autre moyen d'atteindre le même objectif final avec une seule commande ?

Réponse acceptée :

Comme vous l'avez observé, tous les shells ne prennent pas en charge l'expansion des accolades.

Méthode 1 :deux chemins distincts (c'est-à-dire écrire deux fois le préfixe)

Si votre objectif est vraiment de le faire en une seule commande, un moyen simple est :

cp directory/file1 directory/file2 destination

Le cp La commande prend en charge plusieurs arguments source suivis d'un argument de destination. En fait, c'est ce qui se passe avec la commande qui fonctionne pour vous dans Bash. Bash effectue une expansion des accolades, qui convertit la commande que vous avez utilisée en celle indiquée ci-dessus. Autrement dit, lorsque vous exécutez cp directory/{file1,file2} destination dans Bash, le cp la commande ne voit jamais d'accolades.

Une telle commande est simple et facile à comprendre. Je suggère d'y réfléchir.

Méthode 2 :une variable pour le préfixe

Mais si votre objectif est d'éviter de répéter vous-même, alors vous préférerez peut-être ne pas le faire de cette façon, surtout si directory est en fait un long chemin. Après tout, si vous devez modifier le chemin plus tard dans le script, vous devrez apporter des modifications aux deux occurrences.

Vous pouvez stocker le directory (ou quoi que ce soit, chemin vraisemblablement plus long) dans une variable shell :

dir='directory'
cp "$dir/file1" "$dir/file2" destination

$dir est l'expansion des paramètres. Le shell le remplace par la valeur contenue dans la variable dir . Lorsque vous utilisez l'expansion des paramètres, vous ne devez pas omettre les guillemets doubles, sauf dans les rares cas où vous souhaitez que le fractionnement et la globalisation des champs soient effectués. (Cela s'applique également à Bash.)

Ce sont deux commandes, mais si votre objectif réel est d'éviter de vous répéter, c'est peut-être ce que vous voulez. Vous pourriez écrire

dir='directory'; cp "$dir/file1" "$dir/file2" destination

pour en faire "une seule commande", mais ce n'est pas plus court et c'est un peu moins lisible.

(Notez que vous ne pouvez pas simplement supprimer le ; là. Le résultat de faire serait une commande bien formée, mais cela ne ferait pas ce que vous voulez. Il exécuterait le cp commande, en passant une variable d'environnement appelée dir avec la valeur directory dans le cp l'environnement de la commande. Puisque c'est la coquille et non le cp commande, qui développe dir , cela ne fonctionnerait pas.)

Méthode 3 :cd ig au préfixe

Si votre script ne fait rien d'autre après avoir effectué cette opération, ou peu importe le répertoire actuel pour les commandes suivantes, alors if destination est un chemin absolu , vous pouvez utiliser :

cd directory
cp file1 file2 destination

Mais je ne le recommande pas pour les scripts à moins que votre script n'exécute des actions ultérieures qui bénéficient d'être exécutés à partir de ce répertoire, ou peuvent être écrits plus brièvement ou simplement lorsqu'ils sont exécutés à partir de ce répertoire. Sauf lorsque le répertoire à partir duquel un script est exécuté est significatif au but du script, s'y fier peut rendre le script plus difficile à raisonner ; de plus, si le cd la commande réussit mais le cp La commande échoue, les messages d'erreur résultants peuvent être moins qu'entièrement éclairants. Au lieu de cela, je mentionne la technique de cd vers le répertoire source car c'est un modèle utile pour interactive utilisation du shell.

En relation:Comment installer le pilote de l'adaptateur sans fil TP-Link t2uh (Ralink Mt7610u) dans Ubuntu ?

(Comme l'a souligné Hannu, vous pouvez regrouper n'importe quel nombre de commandes dans ( ) pour les exécuter dans un sous-shell et les modifications apportées à l'environnement du shell, y compris l'effet de cd , ne persistera pas après l'exécution de la commande. C'est une technique largement utile, et c'était une omission substantielle que je ne l'avais pas mentionnée. Notez, cependant, que cela n'atténue pas les problèmes liés au fait d'avoir un chemin relatif pour destination .)

Notez que si le cd échoue, les autres commandes continueront généralement à s'exécuter. Cela pourrait copier différents fichiers que vous ne voulez pas copier (s'il existe d'autres fichiers portant les mêmes noms dans le répertoire à partir duquel le script était exécuté) ou produire des messages d'erreur déroutants. Vous pouvez donc préférer :

cd directory && cp file1 file2 destination

Le && entraîne l'exécution de la deuxième commande uniquement si la première commande a réussi. Notez que cela n'annule toujours pas l'effet de l'exécution de la première commande. Une fois le tout exécuté, vous serez toujours dans le directory , sauf si vous l'avez exécuté dans un sous-shell avec ( ) .


Ubuntu
  1. La commande "eval" dans Bash ?

  2. démarrer apachectl à partir de bash

  3. commande d'exportation bash

  4. bash sh - commande introuvable

  5. Bash - Commande de date et espace

Commande d'historique sous Linux (historique de bash)

Commande de sortie Bash et codes de sortie

Commande Bash printf

commande bat sous Linux - alternative à la commande cat

Script bash (II)

Script bash (III)