Почему тест истинного значения возвращается положительным в обоих случаях?

#bash

#bash

Вопрос:

Вот мой сценарий simple.sh

 function b() {
    local a;
    a=$1

        [[ "$a" =~ ^yes* ]]
}


function main(){
    local test;
    test=$(b $1)
        if [[ ${test} ]]; then
        echo Positive I am all good
        fi
        echo The end
}

main $@
  

Я ожидаю, что если я запущу bash simple.sh yes , то он будет печатать

 Positive I am all good
The end
  

но если я запущу bash simple.sh no , он должен напечатать

 The end
  

Однако, когда я запускал скрипт в оболочке, оба print

 The end
  

Почему?

Я использую ubuntu ubuntu.

Если я добавлю -x флаг, я увижу эти следы:

 $ bash -x simple.sh yes
  main yes
  local test
   b yes
   local a
   a=yes
   [[ yes =~ ^yes* ]]
  test=
  [[ -n '' ]]
  echo The end
The end

$ bash -x simple.sh no
  main no
  local test
   b no
   local a
   a=no
   [[ no =~ ^yes* ]]
  test=
  [[ -n '' ]]
  echo The end
The end
  

test по какой-то причине пусто

И bash версия

 bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3 : GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
  

Комментарии:

1. Вы забыли $ [[ test ]] , что это должно быть [[ $test ]] . Строка test всегда принимает значение true .

2. Спасибо! Но теперь Positive I am all good никогда не печатается. Я собираюсь обновить вопрос

3. test пусто, потому $( ) что, как и в test=$(b $1) , фиксирует стандартный вывод. Функция b не записывает stdout (возможно, используя echo ), поэтому ничего не фиксируется. В чем вы ожидаете оказаться test ?

4. @cdarke Так что удаление $() работы? Что заменить $() ?

5. Вы имели в виду `если b $ 1; тогда … `возможно, вместо того, чтобы использовать test ?

Ответ №1:

Со следующей строкой:

 test=$(b $1)
  

вы сохраняете стандартный вывод своей функции b в переменной test , но ваша функция b не имеет вывода, она просто имеет возвращаемое значение, которое не сохраняется. Тогда test переменная всегда будет пустой.

Чтобы использовать возвращаемое значение вашей функции, вы должны либо использовать $? для сохранения test , у вас есть два варианта:

  • вызовите функцию в if
 function b() {
    local a;
    a="$1"

    [[ "$a" =~ ^yes* ]]
}


function main(){
    if  b "$1"; then            # The if will evaluate the return value (0 means true)
        echo "Positive I am all good"
    fi
    echo The end
}

main $@
  
  • сохраните возвращаемое значение и вычислите в if
 function b() {
    local a;
    a="$1"

    [[ "$a" =~ ^yes* ]]
}


function main(){
    local test;
    b $1
    test="$?"
    if [ "${test}" -eq 0 ]; then    # You need to manually evaluate for 0
        echo "Positive I am all good"
    fi
    echo "The end"
}

main $@
  

Комментарии:

1.Синтаксис функции function main or main() , хотя показанный будет работать, он не совсем корректен. Требуется только POSIX main() . Смотрите также unix.stackexchange.com/questions/73750 /.

2. Небольшое семантическое примечание: функции не имеют возвращаемых значений, у них есть статусы выхода , как у любого другого процесса. Различие важно, поскольку статус выхода ограничен тем, чем он может быть (в основном, одним байтом без знака) по сравнению с более широким массивом значений, которые может подразумевать возвращаемое значение.

Ответ №2:

Я лично предпочитаю метод функции if, который многие люди предложили выше, однако вы также можете повторить возвращаемое значение, если хотите сохранить основную функцию такой же, как у вас была раньше:

 function b() {
    if [[ "$1" =~ ^yes* ]]; then
     echo "success"
    fi
}


function main(){
    local test;
    test=$(b $1)
    if [[ ${test} ]]; then
      echo Positive I am all good
    fi
    echo The end
}

main $@in $@