Что означает if [ -n "$(which voltdb 2> /dev/null)" ];?

Что означает if [ -n "$(which voltdb 2> /dev/null)" ];?

У меня очень базовые навыки работы с Linux, и сейчас я пытаюсь разобрать некоторые скрипты оболочки. Я вижу эту строку в одном из скриптов:

if [ -n "$(which voltdb 2> /dev/null)" ];

Я знаю, что /dev/null — это битовый контейнер, который выводит путь, который был бы выполнен, если бы я запустил voltdb в командной строке. Кроме того, вся строка, очевидно, является оператором if. Но меня смущает многое другое.

  1. Почему 2 сравнивается с /dev/null? Похоже, что это несовместимые типы.
  2. Что делает переключатель -n? Я привык использовать переключатели типа rm -r filename, но -n, похоже, не сочетается ни с одной командой
  3. Что делают скобки? Кажется, здесь они означают что-то другое, чем в этом выраженииКаково значение этого тестового выражения []?

В общем, что делает эта строка? Для меня в ней слишком много неизвестных — это как будто слышишь предложение на иностранном языке и пропускаешь так много слов, что не можешь уловить основную структуру.

решение1

В этом фрагменте кода происходит много всего. Работаем изнутри наружу:

which voltdb 2> /dev/null- Команда, выполняемая здесь which, . whichпри вызове будет искать все записи в PATHпеременной среды, чтобы найти команду с именем "voltdb". Если она найдет исполняемый файл с именем "voltdb" в одном из каталогов, указанных в PATH, она выведет полное имя voltdbисполняемого файла.

Чтобы ответить на ваш #1, "2>" является примером перенаправления. Каждый процесс Unix/Linux/*BSD имеет 3 стандартных ввода и вывода, 0 - это stdin, 1 - это stdout, 2 - это stderr. Программы, предназначенные для запуска в командной строке, обычно выводят сообщения об ошибках на stderr. Таким образом, "2> /dev/null" не является числовым сравнением 2 с "/dev/null", он отправляет любой whichвывод об ошибках в /dev/null, специальный файл, который просто съедает любой ввод и возвращает 0 байт вывода.

За пределами этого $(...)конструкция означает «запустить прилагаемую команду и лексически заменить любой вывод прямо здесь, между '$(' и ')'». Это подстановка вывода, то, что делают программы оболочки.

За пределами подстановки вывода фрагмент делает if [ -n "something" ];, где "something" — это то, что whichбыло бы напечатано. "if" — это конструкция потока управления оболочки, которая вызывает выполнение блока кода, когда конвейер команд после "if" завершается со статусом "success".

На самом деле это [исполняемый файл, который просматривает аргументы командной строки вплоть до ]. Флаг "-n" обычно означает "истина для ненулевой длины строки следующего аргумента". Это ответ на ваши вопросы № 2 и № 3. Конструкция [ ... ]дает ответы "истина" (выход с кодом успеха) или "ложь" (выход с кодом ошибки) на некоторые логические условия, в данном случае "ненулевая длина строки".

В конечном итоге этот фрагмент выполнит условие «истина» потока управления if-then-fi или if-then-else-fi, когда voltdbв PATH этой оболочки есть каталог с исполняемым файлом.

решение2

Этот код делает следующее:

if [ -n "...." ];

Оператор if истинен, если результат выполнения кода в двойных кавычках пуст.

Код в двойных кавычках:

$(which voltdb 2> /dev/null)

Запускает which voltdbкоманду и перенаправляет любой вывод этой команды, который появляется на STDERR (стандартная ошибка), в /dev/null. По сути, он нам не интересен, поэтому мы его игнорируем.

Результаты which voltdbвернут путь к любому исполняемому файлу в вашем PATH, который соответствует строке voltdb.

Пример

$ which time
/usr/bin/time

$ which time 2> /dev/null
/usr/bin/time

Что насчет 2>?

2>это сокращенная запись для перенаправления вывода одного изпотокикоторый автоматически настраивается для программы при ее запуске. Потоки следующие:

  • 0 - стандартный вход (STDIN)
  • 1 - стандартный вывод (STDOUT)
  • 2 - стандартная ошибка (STDERR)

Итак, если вы хотите взять вывод STDERR и избавиться от него:

$ which time 2> /dev/null

Если вы хотите взять вывод из STDOUT и перенаправить его в STDERR:

Связанный контент