16 votes

Pourquoi `echo -n` ne fonctionne pas dans ce script sur le terminal mac ?

J'apprends le shell à partir de tutorialspoint aujourd'hui : http://www.tutorialspoint.com/unix/unix-shell-loops.htm

Et j'ai copié ce bloc de code dans un loop.sh fichier :

#!/bin/sh

a=0
while [ "$a" -lt 10 ]    # this is loop1
do
   b="$a"
   while [ "$b" -ge 0 ]  # this is loop2
   do
      echo -n "$b "
      b=`expr $b - 1`
   done
   echo
   a=`expr $a + 1`
done

Mais en l'excutant, j'ai obtenu des choses comme :

...
-n 4
-n 3
-n 2
-n 1
-n 0
...

Apparemment, le -n ne fonctionne pas dans echo -n "$b " .

Puis je déplace le même fichier vers mon système virtuel Ubuntu. Il s'exécute.

J'ai

0
1 0
2 1 0
3 2 1 0
4 3 2 1 0
5 4 3 2 1 0
6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
8 7 6 5 4 3 2 1 0
9 8 7 6 5 4 3 2 1 0

Je suis confus, bien que Ubuntu utilise dash par défaut sh mais l'utilisation d'OSX est officielle bourne shell comme son sh pourquoi le script a échoué ici ? Comment le réparer ?

27voto

Ido Schacham Points 1373

Echo est à la fois un programme binaire ( /bin/echo ) ainsi que des commandes intégrées dans certains shells tels que bash et sh. Comme man echo États,

 Some shells may provide a builtin echo command which is similar or iden-
 tical to this utility.  Most notably, the builtin echo in sh(1) does not
 accept the -n option.  Consult the builtin(1) manual page.

Pour résoudre ce problème, vous pouvez changer votre script pour utiliser bash en mettant la première ligne à

#!/bin/bash

Ou changez votre invocation de echo en

/bin/echo -n "$b "

16voto

jlliagre Points 391

echo n'est pas portable comme vous l'avez constaté. Je vous suggère d'utiliser l'alternative POSIX printf :

printf "$b "

Notez que dans le cas général, si vous ne savez pas à l'avance ce qui contient $b que vous devriez utiliser à la place :

printf "%s " "$b"

2voto

user348173 Points 1013

Ajout de ' \c comme dans la documentation "man echo" a semblé le faire pour moi. Donc ... à la ligne 9, la modification serait la suivante

#!/bin/sh

a=0
while [ "$a" -lt 10 ]    # this is loop1
do
   b="$a"
   while [ "$b" -ge 0 ]  # this is loop2
   do
      echo "$b \c"
      b=`expr $b - 1`
   done
   echo
   a=`expr $a + 1`
done

2voto

Marián Černý Points 111

L'écho intégré pour /bin/sh sur MacOS ne prend pas en charge l'option -n option. Vous pouvez utiliser les alternatives suivantes :

bash

Utilisation de /bin/bash travaux. Mais je n'aime pas l'utiliser pour les scripts car il n'est pas disponible par défaut par exemple sur FreeBSD. Sous Linux, il est disponible.

écho et tr intégrés

Si vous souhaitez utiliser la fonction intégrée echo (par exemple, lorsque vous faites écho d'un mot de passe et que vous ne voulez pas apparaître dans la section ps ) et vous voulez qu'il soit plus portable, vous pouvez utiliser :

echo hello | tr -d '\n'

printf ou /bin/echo

Sinon, printf o /bin/echo -n sont également de bonnes options.

Sachez simplement que printf prend une chaîne de caractères formatée, donc si vous incluez une variable dans la chaîne de caractères qui pourrait inclure un caractère % o \ personnage, ça pourrait casser des choses. Par exemple :

$ w=%world ; printf "hello $w"
printf: %w: invalid directive
hello %

Dans ce cas, vous pouvez utiliser %s comme chaîne de format.

$ w=%world ; printf %s "hello $w"
hello %world

\c suffixe

Une autre option consiste à ajouter \c à la fin de la chaîne de caractères lorsque vous utilisez echo (voir man echo sur MacOS). Il fonctionne bien sur MacOS mais il n'est pas très portable.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X