Hello!

Inspiré(e) de prendre part à la discussion ? Ou de poser une question ou demander de l’aide ?

Alors bienvenues dans les grands sujets des forums de La Bulle : m’inscrire.

Cette partie du forum n’est pas compatible avec les bloqueurs publicitaires

Félicitations à vous, de préférer les accès payants plutôt que la gratuité par la publicité, c’est honnorable et cohérent de votre part. Malheureusement, l’accès payant par micropaiement (qui serait d’environ 1 cent pour 20 pages consultées) n’est pour l’instant pas encore mis en place, et l’accès gratuit sans publicité, est réservé aux membres actif(ve)s du forum. En attendant, si vous souhaitez poursuivre votre visite chez nous, vous pouvez ajouter le site à votre liste blanche, ou encore mieux, désactiver le bloqueur partout. Pour ajouter le site à votre liste blanche, pour Firefox (similaire pour les autres navigateurs), rendez‑vous en bas à gauche de la fenêtre de votre navigateur, et cliquez sur le menu comme dans l’exemple de l’image ci‑dessous, puis rechargez la page, en appuyant sur F5.

Notes sur le Bourne Shell des UNIX
Auteur Message
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Lun 6 Nov 2017 23:08
Message Re: Notes sur le Bourne Shell des UNIX
Hibou a écrit : 
Le caractère d’échappement doit être l’objet de quelques attentions.

[…]

Dans la continuité du précédent message, la section 2.2.3, rappel que la barre oblique inversée (backslash) n’est pas toujours un caractère d’échappement ; dans une chaîne délimitée par des guillemets doubles, elle n’est un caractère d’échappement que quand elle est suivie de $ ou ` ou " ou \ ou un saut de ligne.

Exemple de piège à éviter :

Code : 

$ eval "A=\$(date)"  # Correct, résultat attendu.
$ echo $A
> lundi 6 novembre 2017, 23:00:19 (UTC+0100)

$ eval "B=\$\(date\)" # Piège ! Pas le résultat attendu.
$ echo $B
> $(date)


On comprend mieux avec cet exemple plus simple mais de moindre intérêt pratique :

Code : 

echo "\$(…)"
> $(…)

$ echo "\$\(…\)"
> $\(…\)


Il ne faut pas échapper ce qu’il est inutile d’échapper, au lieu d’être un échappement inutile, ça laisse les deux caractères.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Mar 7 Nov 2017 03:05
Message Re: Notes sur le Bourne Shell des UNIX
D’après 2.8.2, les codes d’erreurs sont comme suit :

  • 1 à 125 : erreur d’expansion ou de redirection.
  • 126 : commande non‑exécutable (ex. droit d’accès, bit exécutable non positionné, …)
  • 127 : commande non‑trouvée.
  • 129 à 255 : commande terminée par un signal.

128 ne semble pas défini et 0 est évidemment pour l’absence d’erreur.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Mer 8 Nov 2017 04:45
Message Re: Notes sur le Bourne Shell des UNIX
À la section 2.9.1, on apprend que les redirections peuvent se placer avant une commande, aussi bien que après comme on a le plus souvent l’habitude. Exactement, les éventuels redirections et assignations de variables apparaissent ensemble avant un commande dans n’importe quel ordre.

Si comme vous le savez probablement, on peut écrire ceci :

Code : 

TRUC="Machin" commande


Au même endroit que l’assignation de la variable, même s’il est bien moins fréquent de le voir, on peut aussi avoir une redirection, comme ceci :

Code : 

>/dev/null ls


Qui est équivalent à :

Code : 

ls >/dev/null


Ceci ne s’applique pas aux commandes composées décrites à la section 2.9.4 :

Code : 

# Incorrect.
$ >/dev/null if true; then echo "A"; echo "B"; fi

# Correct.
$ if true; then echo "A"; echo "B"; fi >/dev/null

# Incorrect.
$ >/dev/null { echo "A"; echo "B"; }

# Correct.
$ { echo "A"; echo "B"; } >/dev/null


Une redirection appliquée à une commande composée, s’applique à toutes les commandes de la commande composée, excepté pour les commandes ayant leur propre redirection. À 2.9.5, on apprend que ce type de redirection avec les commandes composées, s’applique aussi aux corps des fonctions ; les corps des fonctions sont en effet un cas particulier de commandes composées.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Mer 8 Nov 2017 12:13
Message Re: Notes sur le Bourne Shell des UNIX
Encore dans la section 2.9.1, on apprend que l’assignation d’une variable précédant une commande, affecte ou pas l’environnement courant, selon que la commande qui la suit, est une commande prédéfinie du shell ou pas.

Si la commande est une commande externe, l’environnement n’est pas modifié (l’assignation n’est exportée que pour la commande), comme dans le premier cas de l’exemple plus bas. Si la commande est une commande prédéfinie du shell, l’environnement est modifié, comme dans le second cas de l’exemple plus bas. Quand la commande est une fonction, il n’est pas spécifié si l’environnement est modifié ou pas, comme expliqué plus loin.

Code : 

$ TRUC=Machin date  # Date est une commande externe.
> mercredi 8 novembre 2017, 17:22:35 (UTC+0100)
$ echo $TRUC
>

$ TRUC=Machin times # Times est une commande prédéfinie du shell.
> 0m0.000000s 0m0.000000s
> 0m0.000000s 0m0.000000s
$ echo $TRUC
> Machin


À la même section 2.9.1, on apprend que en cas d’assignation de variable précédant une commande invoquant une fonction, l’état de la variable après l’appel de la fonction, n’est pas défini. Plus brièvement, après l’exécution de la fonction, la variable peut retrouver son ancienne valeur ou garder la valeur qui lui été assignée dans la commande d’appel de la fonction, ça dépend de l’implémentation du shell.

Exemple :

Code : 

$ machin() { echo $TRUC; }  # Définition d’une fonction.
$ TRUC=Bidule machin # Appel de la fonction en assignant TRUC.
> Bidule
$ echo $TRUC # Non‑portable !
> Bidule


L’implémentation de Sh que j’utilise, conserve la valeur de la variable, mais on ne peut pas le tenir pour garanti.

Si une commande prédéfinie est implémentée comme une fonction, la commande est quand‑même considérée comme prédéfinie, pas comme une fonction.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Mer 8 Nov 2017 15:48
Message Re: Notes sur le Bourne Shell des UNIX
Toujours d’après 2.9.1, sur les redirections : si comme il est courant de le voir, l’affectation d’une variable, non‑suivie d’une commande, modifie la variable dans l’environnement courant, il n’en va pas de même d’une redirection, qui comme rappelé dans l’avant‑précédent message, peut apparaitre là où une affectation de variable peut apparaitre. Quand elle apparait sous cette forme, une redirection ne redirige pas le flux de l’environnement courant, elle ne s’applique que dans un sous‑shell créé pour l’occasion, et qui finalement ne fait rien (ou je ne vois pas comment). Pour que la redirection s’applique dans l’environnement courant, il faut la faire précéder de exec. Dans ce cas particulier, exec ne remplace pas le shell courant.

Exemple :

Code : 

$ 1>sortie-standard.txt  # N’aura pas l’effet attendu.
$ exec 1>sortie-standard.txt # Correct.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Mer 8 Nov 2017 17:26
Message Re: Notes sur le Bourne Shell des UNIX
À la section 2.9.2, on apprend que l’opérateur de négation logique, “ ! ”, que l’on voit fréquemment dans les expressions de test comme “ if [ ! … ]; then … ”, peut aussi s’utiliser pour les commandes en dehors d’une expression de test. Le statut de sortie renvoyé est alors soit 0 soit 1 : 0 quand la commande s’est terminé avec un statut différent de 0, et 1 quand la commande s’est terminé avec un statut égal à 0.

Exemple :

Code : 

$ ! date
> jeudi 9 novembre 2017, 00:46:18 (UTC+0100)
$ echo $?
> 1

$ ! date -
> date: date incorrecte «-»
$ echo $?
> 0

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Jeu 9 Nov 2017 11:20
Message Re: Notes sur le Bourne Shell des UNIX
À la section 2.9.4, on voit que l’expression conditionnelle d’un “ if ”, d’un “ while ” ou d’un “ until ”, peut être une liste composée, en soulignant bien une liste. Comme le statut d’une liste composée est le statut de sa dernière commande, alors le résultat de l’expression dépend de la dernière commande.

Exemple :

Code : 

$ if false || false || true; then echo OK; fi
> OK

# Possible aussi, mais sans intérêt pratique.
$ if false; false; true; then echo OK; fi
> OK


Les points‑virgule peuvent être remplacés par des sauts de ligne, y compris dans l’expression conditionnelle.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Ven 10 Nov 2017 00:14
Message Re: Notes sur le Bourne Shell des UNIX
À la section 2.9.5, quatre détails importants sur les fonctions.

Les fonctions et les variables, résident dans deux espaces de noms distincts, c’est à dire qu’une variable et une fonction peuvent avoir le même nom, sans que ça ne pose de problème :

Code : 

$ machin() { echo Bidule; }  # Fonction machin.
$ machin=Truc # Variable machin.
$ machin
> Bidule
$ echo $machin
> Truc


Le corps d’une fonction suit la syntaxe d’une commande composée (qui peut être une commande simple), c’est à dire que les accolades ne sont pas toujours nécessaires :

Code : 

$ machin() echo Bidule
$ machin
> Bidule

$ machin() if true; then echo Truc; fi
$ machin
> Truc


Mais si le corps est une liste composée (ce qui est différent d’une commande composée), les accolades sont nécessaires :

Code : 

# Ne donnera pas le résultat attendu.
$ machin() echo Bidule && echo Truc;
> Truc
$ machin
> Bidule

# Correct.
$ machin() { echo Bidule && echo Truc; }
$ machin
> Bidule
> Truc


Comme vous le savez probablement déjà, le « paramètre » $0 d’une fonction, reste le nom du script, pas celui de la fonction.

Il est rappelé qu’une fonction s’utilise comme une commande, ce qui signifie qu’une fonction peut être exécutée en arrière plan, comme avec une commande externe. Dans ce cas, comme avec une commande externe, la fonction est exécutée dans un sous‑shell.

Exemple :

Code : 

$ L="A B C D"
$ machin() for X in $L; do sleep 1s; echo $X; done
$ machin & # Essayez par exemple ls pendant ce temps.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Ven 10 Nov 2017 00:23
Message Re: Notes sur le Bourne Shell des UNIX
À la section 2.10.2, mais ne pas s’en préoccupez plus que nécessaire, il est rappelé que les accolades et le point d’exclamation, sont des mots réservés, pas des opérateurs. Ça peut être important pour appliquer la grammaire du langage du shell, car les contextes où un opérateur peut être reconnu, ne sont pas les mêmes que les contextes où un mot réservé peut être reconnu.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
Administrateur
Avatar de l’utilisateur
  • Genre : Télétubbie
  • Messages : 22173
Ven 10 Nov 2017 11:55
Message Re: Notes sur le Bourne Shell des UNIX
À 2.13.1, deux notes importantes sur les expression régulières dans le shell. L’une de ces deux notes me semble s’appliquer aux chaînes de caractères en général ; ça concerne Unicode.

Les expressions régulières du shell n’ont pas la même syntaxe que les expressions régulière habituelles. Elles supportent quand‑même les ensemble de caractères, comme dans “ [abcde] ”, y compris la négation d’un ensemble de caractère, excepté que le symbole utilisé pour signifié la négation n’est pas “ ^ ” mais “ ! ”, probablement pour raison d’uniformité avec le reste de la syntaxe du langage du shell. La spécification dit que si “ ^ ” est utilisé pour signifier la négation d’un ensemble de caractères, alors le résultat n’est pas défini (c’est à dire variable selon les implémentations de Sh).

Exemple :

Code : 

# Correct.
$ case "b" in [!a]) echo OK; esac
> OK

# Non‑portable !
$ case "b" in [^a]) echo OK; esac
> OK


L’implémentation de Sh que j’utilise, interprète “ ^ ” comme “ ! ”, mais on ne peut pas compter dessus.

Une autre chose à noter et qui s’applique apparemment aux chaînes de caractères en général, est que les expressions régulières du shell, s’appliquent sur la chaîne d’octets représentant les caractères, pas sur les caractères eux‑mêmes. Cela signifie que le shell n’interprète pas les encodages Unicode. Ce n’est pas dit explicitement dans la spécification, ou alors je l’ai manqué, mais c’est probablement ce qui explique que la substitution renvoyant la longueur d’une chaîne de caractères, renvoi la longueur en octets au lieu de la longueur en caractères. Je précise que la longueur en octets dans l’exemple ci‑dessous, est pour UTF‑8.

Exemple :

Code : 

$ S="abcd"
$ echo ${#S}
> 4

$ S="àèçù"
$ echo ${#S}
> 8


UTF‑8 encode les caractères du second cas, sur deux octets chacun, la chaîne de quatre caractères fait huit octets de long, et la substitution donnant la longueur renvoi « 8 ».

C’est une lacune. Il faut penser que quand POSIX a été créé, Unicode et UTF‑8 n’existaient pas encore.

Image
Hibou57

« La perversion de la cité commence par la fraude des mots » [Platon]
Profil Site Internet
cron