Apprenez bash cette semaine et a rencontré un problème.
#!/bin/sh
if [ false ]; then
echo "True"
else
echo "False"
fi
Cela produira toujours True même si la condition semble indiquer le contraire. Si je supprime les crochets []
alors cela fonctionne, mais je ne comprends pas pourquoi.
Vous exécutez la commande [
(ou test
) avec l'argument "false", mais pas la commande false
. Puisque "false" est une chaîne non vide, la commande test
réussit toujours. Pour exécuter la commande, supprimez la commande [
.
if false; then
echo "True"
else
echo "False"
fi
L'instruction if
prend une commande en tant qu'argument (comme le font &&
, ||
, etc.). Le code de résultat entier de la commande est interprété comme un booléen (0/null = true, 1/else = false).
L'instruction test
prend les opérateurs et les opérandes comme arguments et renvoie un code de résultat au même format que if
. Un alias de l'instruction test
est [
, qui est souvent utilisé avec if
pour effectuer des comparaisons plus complexes.
Les instructions true
et false
ne font rien et renvoient un code résultat (0 et 1, respectivement). Ils peuvent donc être utilisés comme littéraux booléens dans Bash. Mais si vous placez les instructions à un endroit où elles sont interprétées comme des chaînes, vous rencontrerez des problèmes. Dans ton cas:
if [ foo ]; then ... # "if the string 'foo' is non-empty, return true"
if foo; then ... # "if the command foo succeeds, return true"
Alors:
if [ true ] ; then echo "This text will always appear." ; fi;
if [ false ] ; then echo "This text will always appear." ; fi;
if true ; then echo "This text will always appear." ; fi;
if false ; then echo "This text will never appear." ; fi;
Ceci est similaire à quelque chose comme echo '$foo'
vs echo "$foo"
.
Lorsque vous utilisez l'instruction test
, le résultat dépend des opérateurs utilisés.
if [ "$foo" = "$bar" ] # true if the string values of $foo and $bar are equal
if [ "$foo" -eq "$bar" ] # true if the integer values of $foo and $bar are equal
if [ -f "$foo" ] # true if $foo is a file that exists (by path)
if [ "$foo" ] # true if $foo evaluates to a non-empty string
if foo # true if foo, as a command/subroutine,
# evaluates to true/success (returns 0 or null)
En bref , si vous voulez simplement tester quelque chose comme succès/échec (ou "vrai"/"faux"), passez une commande à votre instruction if
ou &&
etc., sans crochets. Pour les comparaisons complexes, utilisez des crochets avec les opérateurs appropriés.
Et oui, je sais qu’un type booléen natif n’existe pas dans Bash et que if
, [
et true
sont techniquement des "commandes" et non des "instructions"; ceci est juste une explication très basique et fonctionnelle.
J'ai découvert que je pouvais faire une logique de base en exécutant quelque chose comme:
A=true
B=true
if ($A && $B); then
C=true
else
C=false
fi
echo $C
L'utilisation de true/false supprime un peu d'encombrement des crochets ...
#! /bin/bash
# true_or_false.bash
[ "$(basename $0)" == "bash" ] && sourced=true || sourced=false
$sourced && echo "SOURCED"
$sourced || echo "CALLED"
# Just an alternate way:
! $sourced && echo "CALLED " || echo "SOURCED"
$sourced && return || exit