J'obtiens ce que j'attendais en faisant cela dans bash
:
[ "a" == "a" ] && echo yes
Ça m'a donné yes
.
Mais quand je le fais zsh
, j'obtiens ce qui suit:
zsh: = not found
Pourquoi la même commande ( /usr/bin/[
) se comporte-t-elle différemment dans différents shells?
$PATH
recherche. et==
n'est pas unetest
syntaxe valide pour l'/usr/bin/[
anway. C'est=
bien.Réponses:
Ce n'est
/usr/bin/[
dans aucun des obus. Dans Bash, vous utilisez la commande / intégréetest
[
, et de même dans zsh .La différence est que zsh a également une
=
extension : se=foo
développe sur le chemin de l'foo
exécutable. Cela signifie==
que vous essayez de trouver une commande appelée=
dans votrePATH
. Puisque cette commande n'existe pas, vous obtenez l'erreurque vous avez vu (et en fait, la même chose se produirait même si vous utilisiez réellement
/usr/bin/[
).Vous pouvez utiliser
==
ici si vous le voulez vraiment. Cela fonctionne comme prévu dans zsh:car les guillemets empêchent l'
=word
expansion de fonctionner. Vous pouvez également désactiver l'equals
option avecsetopt noequals
.Cependant, vous feriez mieux:
=
, le test d'égalité compatible POSIX ; ou[[
conditions avec==
à la fois dans Bash et zsh . En général,[[
c'est juste mieux et plus sûr tout autour, y compris en évitant ce genre de problème (et d'autres) en ayant des règles d'analyse spéciales à l'intérieur.la source
[
et[[
? (La recherche sur Google pour[ vs [[
me donne des résultats pourvs
seulement, LOL)[[
prend en charge une plus large gamme de tests dans les deux cas et dispose de règles d'analyse personnalisées qui évitent d'avoir à citer des variables, des opérateurs, etc. Si vous utilisez spécifiquement Bash ou zsh, utilisez[[
. Si vous écrivez un script portable, écrivez dans la commande[
/ compatible POSIXtest
(qui peut ou non être une vraie commande sur votre système en cours d'exécution).[[
et d'oublier qu'il[
existe.[[
est différemment capable. essayer avec elle:for f in *; do [ -e "$f" ] && for a in f d h p S b c; do [ "-$a" "$f" ] && for p in r w x u g; do [ "-$p" "$f" ] || p=-; a=$a$p; done && break; done && printf "%s:\t%s\n" "$a" "$f"; done
.=
/==
est sans doute un cas où[[
n'est pas mieux que[
, comme[[ a == b ]]
est fait « a » correspond au modèle « b » et non est « un » égal à « b » comme on pouvait s'y attendre. Cela signifie que vous devez écrire[[ $a == "$b" ]]
par exemple. Au moins, avec la[
commande, si vous savez comment fonctionne l'analyse des commandes, vous savez que vous devez l'écrire[ "$a" = "$b" ]
pour empêcher l'opérateur split + glob comme dans les autres commandes. Dans cet esprit et si vous n'utilisez pas -a ou -o,[
est sûr dans les implémentations conformes POSIX.Et zsh et bash donnent la même réponse (
type
est intégré aussi pour les deux shells):la source
[
est une commande intégrée au shell en bash et en zsh:Dans la documentation des commandes intégrées de Shell :
La documentation officielle (
$ help test
) ne permet d'utiliser que=
:Ainsi, l'expression correcte serait:
Ce qui se passe, c'est que bash est un peu moins strict. Soutenir l'
==
opérateur avec[
semble être une extension bash et il n'est pas recommandé de l'utiliser:Si vous souhaitez utiliser
==
, vous devez utiliser le[[
mot - clé:Gardez à l'esprit que
[[
c'est moins portable (n'est pas POSIX). Mais bash et zsh le supportent.la source
Dans les deux shells,
bash
etzsh
, l'[
utilitaire est un shell intégré. Il s'agit de l'implémentation des shells de cet outil, il est utilisé de préférence au binaire/usr/bin/[
. Les différents résultats que vous rencontrez sont causés par différentes implémentations.Dans
bash
, l'[
utilitaire accepteCONDITIONAL EXPRESSIONS
comme[[
commande composée. Selon bashs page de manuel à la fois=
et==
sont valables:Dans
zsh
, l'[
utilitaire tente d'implémenter POSIX et ses extensions lorsque ceux-ci sont spécifiés. Dans la spécification de l'utilitaire de test POSIX, aucun==
opérateur n'est défini.la source