web-dev-qa-db-fra.com

erreur de syntaxe près du jeton inattendu '- bash

J'ai écrit un exemple de script sur mon Mac 

#!/bin/bash
test() {
  echo "Example"
}
test
exit 0

et cela fonctionne bien en affichant Exemple

Lorsque je lance ce script sur une machine RedHat, il est écrit:

erreur de syntaxe près d'un jeton inattendu '

J'ai vérifié que bash est disponible en utilisant

cat /etc/shells

which bash shows /bin/bash 

Quelqu'un at-il rencontré le même problème?

Merci d'avance !

12
user3155779

Ce pourrait être un problème d'encodage de fichier.

J'ai rencontré des problèmes d'encodage de type de fichier lorsque je travaillais sur des fichiers entre différents systèmes d'exploitation et éditeurs - dans mon cas en particulier entre les systèmes Linux et Windows.

Je suggère de vérifier le codage de votre fichier pour vous assurer qu'il convient à l'environnement linux cible. Je suppose qu’un problème d’encodage est moins probable étant donné que vous utilisez un MAC que si vous aviez utilisé un éditeur de texte Windows, mais je pense que l’encodage de fichier mérite tout de même l’être.

--- EDIT (Ajouter une solution réelle comme recommandé par @Potatoswatter) 

Pour illustrer le problème que pourrait poser le type de fichier, j'ai copié/collé votre script d'exemple dans le Bloc-notes sous Windows (je n'ai pas accès à un Mac), puis je l'ai copié sur un ordinateur Linux et exécuté: 

jdt@cookielin01:~/windows> sh ./originalfile             
./originalfile: line 2: syntax error near unexpected token `$'{\r''
'/originalfile: line 2: `test() {

Dans ce cas, le Bloc-notes a enregistré le fichier avec les retours à la ligne et les sauts de ligne, provoquant l’erreur indiquée ci-dessus. Le \r indique un retour à la ligne (les systèmes Linux terminent les lignes avec des sauts de ligne \n uniquement). 

Sur la machine Linux, vous pouvez tester cette théorie en exécutant ce qui suit pour supprimer les retours chariot du fichier, s’ils sont présents:

cat originalfile | tr -d "\r" > newfile

Puis essayez d’exécuter le nouveau fichier sh ./newfile. Si cela fonctionne, le problème était les retours chariot sous forme de caractères masqués. 

Remarque: Il ne s'agit pas d'une réplication exacte de votre environnement (je n'ai pas accès à un Mac), mais il me semble probable que le problème est qu'un éditeur, quelque part, un chariot enregistré retourne dans le fichier. 

--- /MODIFIER 

Pour élaborer un peu, les systèmes d'exploitation et les éditeurs peuvent avoir des valeurs par défaut d'encodage de fichier. En règle générale, les applications et les éditeurs influent sur le codage de type de fichier utilisé. Par exemple, je pense que Microsoft Notepad et Notepad ++ utilisent Windows-1252 par défaut. Il peut également y avoir des différences entre les nouvelles lignes à prendre en compte (dans les environnements Windows, un retour à la ligne et un saut de ligne sont souvent utilisés pour terminer les lignes de fichiers, tandis que sous Linux et OSX, seul un saut de ligne est généralement utilisé). 

Une question et une réponse similaires faisant référence au codage de fichier se trouvent ici: caractère incorrect apparaissant dans l'exécution du script bash

25
jdt

Un moyen facile de convertir le fichier example.sh en UNIX si vous travaillez sous Windows consiste à utiliser le Bloc-notes ++ (Édition> Conversion EOL> Format UNIX/OSX)

Vous pouvez également définir l'EOL par défaut dans le Bloc-notes ++ (Paramètres> Préférences> Nouveau document/répertoire par défaut> sélectionnez Unix/OSX dans la zone Format).

4
JAR

essayez quelque chose comme

$ Sudo apt-get install dos2unix
$ dos2unix offendingfile
4
Amos Folarin

Merci @jdt pour votre réponse.

Suite à cela, et depuis que je continue à avoir ce problème avec retour chariot, j'ai écrit ce petit script. N'exécutez que carriage_return et vous serez invité à "nettoyer" le fichier.

https://Gist.github.com/kartonnade/44e9842ed15cf21a3700

alias carriage_return=remove_carriage_return
remove_carriage_return(){

# cygwin throws error like : 
# syntax error near unexpected token `$'{\r''
# due to carriage return
# this function runs the following
# cat originalfile | tr -d "\r" > newfile

read -p "File to clean ? "
file_to_clean=$REPLY
temp_file_to_clean=$file_to_clean'_'

# file to clean => temporary clean file
remove_carriage_return_one='cat '$file_to_clean' | tr -d "\r" > '
remove_carriage_return_one=$remove_carriage_return_one$temp_file_to_clean

# temporary clean file => new clean file
remove_carriage_return_two='cat '$temp_file_to_clean' | tr -d "\r" > '
remove_carriage_return_two=$remove_carriage_return_two$file_to_clean

eval $remove_carriage_return_one
eval $remove_carriage_return_two
# remove temporary clean file 
eval 'rm '$temp_file_to_clean

}

2
kartonnade

Je veux ajouter à la réponse ci-dessus est comment vérifier si c'est un problème de retour chariot dans Unix comme environnement (j'ai testé sous MacOS)

1) Utiliser un chat

cat -e my_file_name

Si vous voyez que les lignes se terminent par ^M$, alors oui, il s'agit du problème du retour chariot.

2) Trouver la première ligne avec le caractère retour chariot

grep -r $'\r' Grader.sh | head -1

3) Utiliser vim

vim my_file_name

Puis dans vim, tapez

:set ff

Si vous voyez fileformat=dos, le fichier provient d'un environnement DOS qui contient un retour à la ligne.

Après avoir découvert, vous pouvez utiliser les méthodes mentionnées ci-dessus par d'autres personnes pour corriger votre fichier.

0
traceformula