web-dev-qa-db-fra.com

Pourquoi est-ce que j'obtiens "ligne 1: $ ': \ r': commande introuvable"?

J'ai utilisé Cygwin sur mon ordinateur portable (DOS). J'ai une collection de scripts de mes collègues et la mienne. Je ne suis pas un informaticien, je ne connais pas Unix. Je suis la syntaxe de mes collègues et capable de gérer quelques choses simples.

Les scripts fonctionnaient bien sur mon ancien ordinateur portable. Je viens de changer d'ordinateur portable, d'installer Cygwin. Lorsque j'exécute mes scripts, ils ne fonctionnent pas. Voici un exemple du message d'erreur que j'obtiens:

line 1: $':\r': command not found
line 5: syntax error near unexpected token `$'\r''
line 5: `fi

Voici les 5 premières lignes de mon script

:
iter=1
if [ -f iter.txt ]
   then rm ./iter.txt 
fi  

Quelqu'un peut-il expliquer comment je peux contourner ce problème?

13
TPham

Vous avez des fins de ligne de style Windows.

La commande no-op : est lu à la place comme :<carriage return>, affiché comme :\r ou plus complètement comme $':\r'.

Courir dos2unix scriptname et ça devrait aller.


Si vous n'avez pas dos2unix, ce qui suit devrait fonctionner presque n'importe où (et j'ai testé sur MobaXterm sous Windows):

vi -b filename

Puis dans vi, tapez:

:%s/\r$//
:x

Vous êtes prêt à partir.


Dans vim, qui est ce que vous utilisez sur Cygwin pour vi, il existe plusieurs façons de procéder. Un autre implique le paramètre fileformat, qui peut prendre les valeurs dos ou unix. Soit le modifier explicitement après avoir chargé le fichier avec

set fileformat = unix
: w + fileformat = unix

Pour plus d'informations à ce sujet, consultez les nombreuses questions et réponses couvrant ce sujet, notamment:

29
Wildcard

Cela est dû au fait que le script a été enregistré par un éditeur qui utilise des fins de ligne DOS (comme Notepad ++, par exemple). Vous devrez les supprimer de vos scripts.

Pour ce faire, utilisez soit dos2unix Sur le fichier de script, soit

$ tr -d '\r' <script >script.new && mv script.new script

(cela supprimera tous les retours chariot de n'importe où dans le script)


Quant au code du script:

:
iter=1
if [ -f iter.txt ]
   then rm ./iter.txt 
fi  

Cela devrait ressembler à quelque chose

iter=1
if [ -f "./$iter.txt" ]; then
   rm "./$iter.txt"
fi

Cela supprime le fichier 1.txt Du répertoire actuel, s'il existe. La commande : Ne fait rien (presque) et peut être supprimée. La valeur de la variable iter doit être utilisée comme $iter, Et être citée. Et puis je suis peut-être plus explicite que nécessaire en utilisant ./ Pour dire que le fichier doit être trouvé dans le répertoire courant.

Si vous prévoyez de transformer cela en boucle (ici, en supprimant tous les fichiers 1.txt, 2.txt, ..., 10.txt):

iter=1
while [ "$iter" -le 10 ]; then
    if [ -f "./$iter.txt" ]; then
        rm "./$iter.txt"
    fi
    iter=$(( iter + 1 ))
done

Ou, si nous nous sentons sournois/paresseux,

rm -f {1..10}.txt

dans les coquilles qui comprend l'expansion de l'accolade.

10
Kusalananda

Vos scripts ont des terminaisons de ligne incorrectes. Windows utilise CR + LF (\ r\n), Unix utilise LF (\ n) et Classic MacOS utilise CR (\ r). Vous devrez modifier les fins de ligne sur tous les fichiers concernés, soit avec un éditeur de texte, soit avec un outil autonome comme dos2unix.

Les systèmes FTP et de contrôle de version tels que SVN ont tendance à être capables de convertir les fins de ligne de manière appropriée, donc vous voudrez peut-être examiner ces options pour le transfert de fichiers à l'avenir.

Si ces fichiers ne sont pas en cours de transfert, mais simplement utilisés sur une seule machine, alors vous voudrez trouver les paramètres des fins de ligne dans votre éditeur de texte préféré. La plupart de ceux qui sont annoncés comme "pour les programmeurs" auront une telle option.

5
Fox

En guise de réponse supplémentaire, permettez-moi d'ajouter quelques notes/conseils ...

Tout d'abord, pour les fichiers texte normaux, vous pouvez facilement déterminer s'ils ont une ligne Unix ou DOS se terminant à l'aide de la commande file. Par exemple:

$ file test.txt
test.txt: ASCII text, with CRLF line terminators
$ dos2unix test.txt
dos2unix: converting file test.txt to Unix format...
$ file test.txt
test.txt: ASCII text

Notez mon utilisation de dos2unix. Je vous recommande fortement de l'installer. Selon la façon dont vous utilisez Cygwin, vous pouvez constater que vous devez effectuer cette conversion suffisamment souvent pour que la commodité soit la bienvenue. Plus important encore, il n'y a aucun risque d'erreur comme vous obtenez avec les modifications manuelles décrites ici.

Pour installer, démarrez l'exécutable Cygwin principal. C'est celui avec le nom comme setup-x86_64.exe ou quelque chose dans ce sens. Assurez-vous de voir un écran comme celui-ci:

enter image description here

Comme vous avez déjà effectué l'installation principale, vous devriez pouvoir cliquer sur Suivant jusqu'à ce que vous obteniez l'écran de sélection. Sélectionnez Complet dans la liste déroulante et entrez "dos2" dans la zone de recherche et choisissez l'outil comme indiqué ici:

enter image description here

Cliquez à nouveau sur Suivant et laissez l'installation se terminer. C'est ça. S'amuser. Cygwin, à l'exception de cet inconvénient occasionnel, est un package génial.

3
B Layer

Sinon dos2unix, il y a aussi 'flip'

$ flip -u votrefichier.txt

le retournera en utilisant les fins de ligne unix.

1
chai

J'utilise Notepad ++ pour éditer mes scripts bash (.sh) en me connectant au serveur par WinSCP
(Pour configurer l'éditeur WinSCP sur Notepad ++: https://winscp.net/eng/docs/ui_editor_preferences )

C'est très pratique pour ouvrir des fichiers depuis des serveurs pour les éditer/enregistrer au lieu de l'éditeur " Vim ".
Lorsque vous ouvrez le fichier dans Notepad ++ , double-cliquez sur la 7e colonne dans la barre d'état en bas et sélectionnez " Unix (LF) ".

enter image description here

De plus, vous devez changer le 8ème en encodant -> Encoder en UTF-8 dans la barre supérieure.

1
Alper t. Turker

Vous n'avez pas besoin de modifier l'encodage de ligne du fichier réel pour que Bash de Cygwin fonctionne avec bonheur avec les encodages de fin de ligne Mac et Windows. Il y a une option que vous devez simplement activer.

Mettez simplement à jour votre ~/.bash_profile donc il contient

export SHELLOPTS
set -o igncr

Voir https://ptolemy.berkeley.edu/projects/chess/softdevel/faq/5.html

0
swdev