Bash if [false]; возвращает true



учился баш на этой неделе и наткнулся на корягу.



#!/bin/sh

if [ false ]; then
echo "True"
else
echo "False"
fi


это всегда будет выводить True, хотя условие, казалось бы, указывает на обратное. Если я сниму скобки [] затем он работает, но я не понимаю, почему.

654   4  

4 ответов:

вы находитесь под управлением [ (Он же test) команда с аргументом "false", не выполняющая команду false. Поскольку "false" является непустой строкой, то test команда всегда выполняется успешно. Чтобы фактически выполнить команду, отбросьте

быстрый логический праймер для Bash

The if оператор принимает команду в качестве аргумента (как и &&,|| и т. д.). Целочисленный результирующий код команды интерпретируется как логическое значение (0 / null=true, 1/else=false).

The test оператор принимает операторы и операнды в качестве аргументов и возвращает код результата в том же формате как if. Псевдоним test заявление [, который часто используется с if для выполнения более сложных сравнений.

The true и false операторы ничего не делают и возвращают результат код (0 и 1, соответственно). Таким образом, они могут быть использованы в качестве булевых литералов в Bash. Но если вы поместите операторы в место, где они интерпретируются как строки, вы столкнетесь с проблемами. В вашем случае:

if [ foo ]; then ... # "if the string 'foo' is non-empty, return true"
if foo; then ...     # "if the command foo succeeds, return true"

так:

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;

это похоже на что-то вроде echo '$foo' и echo "$foo".

при использовании test заявление, результат зависит от используемых операторов.

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)

короче, если вы просто хотите проверить что-то как pass/fail (aka "true"/"false"), то передайте команду своему if или && etc. заявление, без скобок. Для сложных сравнений используйте скобки с соответствующими операторами.

и да, я знаю, что нет такой вещи, как родной логический наберите в Баш, а то if и [ и true являются технически "командами", а не "утверждениями"; это просто очень простое, функциональное объяснение.

Я обнаружил, что я могу сделать некоторые основные логики, запустив что-то вроде:

A=true
B=true
if ($A && $B); then
    C=true
else
    C=false
fi
echo $C

С помощью true / false удаляет некоторые скобки беспорядок...

#! /bin/bash    
#  true_or_false.bash

[ "$(basename )" == "bash" ] && sourced=true || sourced=false

$sourced && echo "SOURCED"
$sourced || echo "CALLED"

# Just an alternate way:
! $sourced  &&  echo "CALLED " ||  echo "SOURCED"

$sourced && return || exit

Comments

    Ничего не найдено.