web-dev-qa-db-fra.com

Affectation d'un code de sortie à une variable locale Shell

#!/bin/bash
function0()
{
 local t1=$(exit 1)
 echo $t1
}

function0

echo imprime une valeur vide. J'esperais:

1

Pourquoi t1 variable obtient la valeur de retour de la commande exit - 1?

46
user93868

local t1=$(exit 1) indique au Shell:

  • exécutez exit 1 dans un sous-shell;
  • stocker sa sortie (comme dans, le texte qu'il sort en sortie standard) dans une variable t1, locale à la fonction.

Il est donc normal que t1 Finisse par être vide.

($() est connue sous le nom de substitution de commande .)

Le code de sortie est toujours attribué à $?, Vous pouvez donc

function0()
{
  (exit 1)
  echo "$?"
}

pour obtenir l'effet que vous recherchez. Vous pouvez bien sûr affecter $? À une autre variable:

function0()
{
  (exit 1)
  local t1=$?
  echo "$t1"
}
62
Stephen Kitt

Le code de sortie a été stocké dans la variable $? . En utilisant Substitution de commandes uniquement pour capturer la sortie, vous devez utiliser (...) pour créer un sous-shell :

#!/bin/bash

func() {
  (exit 1)
  local t1=$?
  printf '%d\n' "$t1"
}

func
12
cuonglm

Dans bash cela fonctionne:

loc(){  local   "x=$(exit "$1"):$?"
        printf  '$%s:\t%d\n' \
                 x "${x##*:}" \? "$?"
}

Cela concerne l'ordre d'évaluation des commandes et l'affectation des variables. local a une valeur de retour qui lui est propre - et c'est la commande en cours d'exécution, pas la substitution de commande. La raison pour laquelle des choses comme ...

x=$(exit 1); echo "$?"

... peut renvoyer 1 parce qu'il n'y a jamais de retour dans cette commande, sauf pour l'exécution du sous-shell pour affecter la valeur de $x - donc $? ne se fait pas encombrer comme il le fait pratiquement tous les autres cas dans lesquels des substitutions de commandes sont utilisées.

Quoi qu'il en soit, avec local it does se fait encombrer - mais si vous l'attrapez au bon moment - c'est-à-dire pendant que les extensions sont toujours en cours d'évaluation et avant Les routines de local ont une chance de l’encombrer - vous pouvez toujours l’attribuer.

unset x; loc 130; echo "${x-\$x is unset}"

... impressions ...

$x: 130
$?: 0
$x is unset

Vous devez savoir cependant que dans de nombreux shells, vous ne pouvez pas vous fier à ce que $? Soit défini de cette manière à mi-évaluation. En fait, c'est probablement parce que ces shells ne prennent pas la peine de réévaluer à chaque étape possible comme peut-être bash - ce qui, selon moi, est probablement un meilleur comportement que celui de bash. Voulez-vous vraiment que votre interprète évalue de manière récursive des valeurs de boucle qui seront très probablement écrasées avant que vous ayez la chance de les utiliser?

Quoi qu'il en soit, c'est comme ça que vous pouvez faire.

7
mikeserv