рыбья скорлупа. Как проверить, установлена ​​ли переменная или пуста?

Как я могу сделать что-то вроде

set variable (some_command_that_may_return_a_string)
if [ variable is set ]
    do_something

и наоборот, как проверить, пуста ли переменная?


person Adam Zahran    schedule 10.12.2017    source источник


Ответы (2)


  • set -q var (обратите внимание на отсутствующий "$" — здесь используется переменная name) можно использовать для проверки того, установлена ​​ли переменная.

  • set -q var[1] можно использовать для проверки того, был ли назначен первый элемент переменной (т. е. не является ли он пустым в виде списка).

  • test -n "$var" [fn0] (или [ -n "$var" ]) можно использовать для проверки того, расширяется ли переменная в непустую строку (и test -z является обратным - верно, если она пуста).

Они будут истинными/ложными в несколько иных обстоятельствах.

Когда set var вообще не выполнялось (и оно не было унаследовано от родительского процесса), set -q var, set -q var[1] и test -n "$var" будут ложными, test -z "$var" будет истинным.

Когда будет сделано что-то вроде set var (без каких-либо дополнительных аргументов), set -q var будет истинным, set -q var[1] будет ложным.

Когда будет сделано что-то вроде set var "", обе версии set будут верны.

Когда будет сделано что-то вроде set var "somestring" (или даже set var "" "" [fn1]), sets будет истинным, а test -z "$var" будет ложным.


[fn0]: вы никогда не хотите использовать test (или [) без кавычек переменной. Одним особенно вопиющим примером является то, что test -n $var вернет true как в том случае, если переменная что-то содержит, так и в том случае, если она пуста/не задана в списке (вообще нет set или set var без аргументов). Это связано с тем, что test рыбы является одной из немногих частей, которые следуют POSIX, и это требует, чтобы test с любым одним аргументом было истинным. Также он не обрабатывает списки должным образом - test -n $var будет иметь странные результаты, если var имеет более одного элемента.

[fn1]: Это связано с тем, что список будет расширен как строка путем соединения элементов пробелами, поэтому список, состоящий из двух пустых строк, будет расширен до " " - одного пробела. Поскольку это не пусто, test -z возвращает false.

person faho    schedule 10.12.2017
comment
Как это входит в оператор if? - person Gringo Suave; 24.08.2020
comment
Как и все в шеллскрипте, if и все такое. Итак, if set -q var[1], if test -n "$var" и так далее. if принимает не условие, а команду для вызова и использует свой статус выхода. - person faho; 25.08.2020

@faho дал отличный ответ, но я подумал, что было бы проще, если бы был пример кода.

function if-test-no-arg
  set var

  if set -q var
    # true
  end

  if set -q var[1]
    # false
  end

  # Always put quotation marks
  if test -n "$var"
    # false
  end

  if test -z "$var"
    # true
  end
end

function if-test-empty-arg
  set var ""

  if set -q var
    # true
  end

  if set -q var[1]
    # true
  end

  if test -n "$var"
    # false
  end

  if test -z "$var"
    # true
  end
end

function if-test-valid-arg
  set var "hello"

  if set -q var
    # true
  end

  if set -q var[1]
    # true
  end

  if test -n "$var"
    # true
  end

  if test -z "$var"
    # false
  end
end

function if-test-no-set
  if set -q var
    # false
  end

  if set -q var[1]
    # false
  end

  if test -n "$var"
    # false
  end

  if test -z "$var"
    # true
  end
end
person Sanghyun Lee    schedule 26.05.2021