#bash #shell #logic
#bash #оболочка #Логические
Вопрос:
Любой способ объединить эти два оператора IF в один…
if [ -n "$(system_profiler SPPrintersDataType | grep Shared | grep Yes)" ]; then
echo 1
fi
if [ -n "$(system_profiler SPPrintersDataType | grep 'System Printer Sharing: Yes')" ]; then
echo 1
fi
Комментарии:
1. Это зависит от того, каким вы хотите получить результат. Вывод 1, если оба условия верны? Любое условие? Вывести отдельный 1 для каждого условия, которое является истинным?
Ответ №1:
Добавить ||
оценку короткого замыкания между ними:
if [ -n ... ] || [ -n ... ]; then ## Something; fi
||
обрабатывается как логическое ИЛИ (и amp;amp;
является логическим И).
В вашем случае:
if [ -n "$(system_profiler SPPrintersDataType | grep Shared | grep Yes)" ] || [ -n "$(system_profiler SPPrintersDataType | grep 'System Printer Sharing: Yes')" ]; then
echo 1
fi
Просто обратите внимание, что если вы используете ключевое слово bash [[
, то также допустимо следующее:
if [[ -n ... || -n ... ]]; then ## Something; fi
Комментарии:
1. Это решение неверно, ИМХО, потому что ваше условие срабатывает только в том случае, если присутствуют обе строки, в то время как код в исходной публикации срабатывает, если присутствует хотя бы одна из строк.
2. @user1934428 Поддержан. Отредактировано.
Ответ №2:
[[ -n $(system_profiler SPPrintersDataType | grep Shared | grep Yes)$(system_profiler SPPrintersDataType | grep 'System Printer Sharing: Yes') ]] amp;amp; echo 1
Примечание:
-
Вы хотите повторить 1, если одна из строк непустая или если другая непустая. В этом случае проще связать строки и посмотреть на результат: если результат непустой, по крайней мере, одна из строк imput должна быть непустой.
-
В этом случае нет необходимости использовать
if
оператор (хотя это и не запрещено). -
Вам не нужно заключать аргумент в кавычки
-s
, если вы используете[[ ... ]]
для тестирования строки. -
Когда вы выполняете grep для Shared, должно ли быть разрешено, чтобы слово Yes появлялось перед словом Shared в строке? Если нет, было бы проще написать
grep 'Shared.*Yes
. -
Поскольку вас интересует не фактический вывод команды grep, а только тот факт, что он соответствует, что-то вроде этого также будет работать:
{system_profiler SPPrintersDataType|grep -q 'Shared.*Yes} || {system_profiler SPPrintersDataType|grep -Fq 'System Printer Sharing: Yes'} amp;amp; echo 1
-
Наконец, предполагая, что команда system_profiler выдает один и тот же результат в обоих вызовах, код можно упростить до:
{system_profiler SPPrintersDataType|grep -Eq 'Shared.*Yes|System Printer Sharing: Yes'} amp;amp; echo 1
Это в основном говорит: если в system_profiler есть строка, которая содержит Shared…Да ИЛИ строка, содержащая общий доступ к системному принтеру Да, затем echo 1 . Вам нужен -E в порядке, чтобы заставить |
его работать в шаблоне регулярных выражений.
По общему признанию, все эти предложения означают, что вы получаете только один 1
эхо-сигнал, если условие выполнено, в то время как в вашем исходном решении вы получаете два 1
эхо-сигнала, если выполняются оба условия. Поэтому мое решение не совсем эквивалентно вашему. Однако, поскольку вы явно сказали, что хотите объединить случаи, я думаю, это приемлемо.
Комментарии:
1. Хорошо, добавлены пояснения.
Ответ №3:
Я не знаю, как system_profiler
выглядит ваш результат, поэтому здесь немного наугад. Если Shared
и Yes
всегда находятся в одном и том же порядке в строке, вы можете использовать grep для них вместе с
grep 'Shared.*Yes'
и вы можете выполнить grep для обоих ваших выражений за один проход с помощью
grep 'Shared.*Yes|System Printer Sharing: Yes'
Затем вы можете записать свою команду в виде
system_profiler SPPrintersDataType
| grep -q 'Shared.*Yes|System Printer Sharing: Yes'
amp;amp; echo 1
Обратите внимание, что мы используем grep -q
для подавления вывода, поскольку нас интересует только код возврата.
Обратите внимание также, что если присутствуют обе строки, мы выводим только одну 1
— я предполагаю, что это то, что вы хотите, но я упоминаю об этом, поскольку это отличается от вашего скрипта.