Когда код состояния бесполезен, есть ли способ построить конвейер на основе вывода из stdout?
Я бы предпочел, чтобы ответ был не на сценарии использования, а на вопросе сценариев оболочки. Я пытаюсь найти наиболее конкретный пакет, доступный в репозитории, угадав имя на основе кодов страны и языка.
Возьмите, к примеру, это,
$PACKAGE1=hunspell-en-zz
$PACKAGE2=hunspell-en
Первое предположение более уместно, но оно может не существовать. В этом случае я хочу return hunspell-en
( $PACKAGE2
), потому что первая опция hunspell-en-zz
( $PACKAGE1
) не существует.
конвейеры apt-кеша
Команда apt-cache
возвращает успех (который определяется оболочкой как код выхода ноль) всякий раз, когда команда может быть запущена (из документов apt-cache
)
apt-cache возвращает ноль при нормальной работе, десятичное 100 при ошибке.
Это делает использование команды в конвейере более сложным. Обычно я ожидаю, что эквивалент 404 при поиске пакета приведет к ошибке (как это случилось бы с curl
или wget
). Я хочу выполнить поиск, чтобы увидеть, существует ли пакет, и если нет, использовать другой пакет, если он существует .
Это ничего не возвращает, так как первая команда возвращает успех (поэтому rhs в ||
никогда не выполняется)
apt-cache search hunspell-en-zz || apt-cache search hunspell-en
apt-cache search
с двумя аргументами
Это ничего не возвращает, поскольку apt-cache
ANDs его аргументы,
apt-cache search hunspell-en-zz hunspell-en
Из документов apt-cache
Отдельные аргументы могут использоваться для указания нескольких шаблонов поиска, которые объединяются и объединяются.
Так как один из этих аргументов явно не существует, это ничего не возвращает.
Вопрос
Какова идиома оболочки для обработки соглашений, подобных тем, в apt-cache
которых код возврата бесполезен для задачи? А успех определяется только наличием выхода на STDOUT?
Похожий на
потерпеть неудачу, когда ничего не было найдено
они оба вытекают из одной и той же проблемы. Выбранный ответ там упоминает,
find -z
что, к сожалению, не применимо решение здесь и является конкретным вариантом использования. Там нет упоминания об идиоме или построении конвейера без использования нулевого завершения (опция не включенаapt-cache
)
источник
hunspell-en
существует? В любом случае, вы можете использоватьapt-cache policy
и grep для^$PACKAGENAME:
.hunspell-ar
существуют и пакетов с названиями стран нет. Мне нужно найти наиболее точный пакет для данной страны и языка.find
какapt-cache
в этом отношении - бесполезный код возврата, успех основан на выводе.-z
что, к сожалению, это не решение, поэтому проблема, связанная с конкретным случаем, не применима. И нет никакого упоминания об идиоме или построении конвейера без использования нулевого завершения (неapt-cache
find
что он будет использоваться с-print0
и, таким образом, grep с-z
. Поскольку apt-cache не дает вывод с нулевым символом в конце, вам это не нужно-z
.Ответы:
Создайте функцию, которая принимает команду и возвращает true, если она имеет какой-либо вывод.
Так что для этого варианта использования это будет работать так,
источник
r printf '\n\n\n'
что вернет false. С другими оболочкамиzsh
,r printf '\0\0\0'
также будет возвращено ложное Так было быr printf '\0a\0b\0c'
с некоторыми снарядами.Насколько я знаю, не существует стандартного способа справиться с теми случаями, когда успех команды определяется наличием выходных данных. Вы можете написать обходные пути, хотя.
Например, вы можете сохранить выходные данные команды в переменной, а затем проверить, является ли эта переменная пустой или нет:
Я думаю, что это отвечает на вопрос в общих чертах, но если мы поговорим о
apt-cache search
некоторых решениях, мне в голову.У меня есть скрипт, который делает управление пакетами проще. Вот некоторые из его функций:
Они позволяют выполнять несколько поисков в одной команде. Например:
Каждая функция выполняет поиск в базе данных по-своему, поэтому результаты могут отличаться в зависимости от используемой вами функции:
источник
Я не назвал бы это изящным, но я думаю, что это могло бы сделать работу:
У меня нет машины Debian для тестирования, к сожалению. Я включил
-n
опцию «только для имен»,apt-cache
чтобы попытаться ограничить результаты поиска, так как похоже, что вы в основном уверены в том, что ищете.Может быть запущен как:
источник
-q
тихим вариантом? Страница man не очень многословна, но, возможно, она меняет возвращаемые значения?Муру уточнил это в комментариях
grep
вернет статус 1, если нет ввода. Таким образом, вы можете добавитьgrep .
в поток, и если нет ввода, соответствующего шаблону.
, он изменит код состояния:Для варианта использования, который выглядит следующим образом. В ниже нет,
-pl-pl
поэтому он отступает и возвращаетсяhunspell-pl
Или,
Там
-en-US
так и возвращаетсяhunspell-en-us
.Смотрите также,
источник
grep .
возвращает значение true, если входные данные содержат хотя бы одну (полностью ограниченную некоторыми реализациями) строку, которая содержит хотя бы один символ (хорошо сформированный для большинства реализаций), и в противном случае удалят пустые строки.grep '^'
будет лучше работать при проверке наличия выходных данных, хотя в некоторых реализациях может все еще возвращать false, если входные данные представляют собой одну строку без разделителей (и может удалить эту строку или в других реализациях вернуть true, но добавить отсутствующий символ новой строки). Некоторые реализации grep также подавляют символ NUL.Вы можете определить:
А потом:
Некоторые
awk
реализации могут подавить NUL-символы на входе.В противоположность
grep '^'
этому вышеописанное гарантированно будет работать с вводом, который не заканчивается символом новой строки, но добавляет недостающий символ новой строки.Чтобы избежать этого и быть переносимым на системы, где
awk
задыхается NUL, вы можете использоватьperl
вместо этого:С помощью
perl
вы также можете определить вариант, который обрабатывает произвольные файлы более изящно:Это ограничивает использование памяти (например, для файлов, в которых нет символов новой строки, таких как большие разреженные файлы).
Вы также можете создавать варианты, такие как:
или:
(имейте в виду, что определение пробела варьируется в зависимости от
awk
реализации, в некоторых случаях оно ограничено пробелом и табуляцией, в некоторых также включены символы ASCII с вертикальным интервалом, такие как CR или FF, а в некоторых - пробелы локали)В идеале в Linux вы должны использовать
splice()
системный вызов для максимизации производительности. Я не знаю команду, которая бы выставляла ее, но вы всегда можете использоватьpython
sctypes
:(обратите внимание, что либо
has_output
stdin, либо stdout (или оба) должны быть каналом дляsplice()
работы).источник
Я бы предложил использовать очень простые встроенные функции оболочки:
Вот самый простой тестовый пример:
Тогда вы можете легко использовать его с той
||
конструкцией, к которой вы привыкли:Эта простая функция будет работать так, как вам хотелось бы с вашим
apt_cache
поведением, каким бы ни было количество аргументов.источник
ck_command echo 'asdf' | cat
ничего не выводит.