Я не уверен, имели ли вы в виду '|' или '||' во втором случае.
'|' в командной оболочке передает вывод одной команды на вход другой - обычным примером является что-то вроде:
curl http://abcd.com/efgh | grep ijkl
т.е. запустить команду и использовать другую команду для обработки вывода команды.
В приведенном вами примере это довольно бессмысленно, поскольку 'cd' обычно не генерирует никакого вывода, а 'pwd' не ожидает никакого ввода.
'&&' и '||' - это команды-партнеры. Они предназначены для использования так же, как логические операторы "and" и "or" в большинстве языков. Однако выполняемая оптимизация придает им специфическое поведение, которое является парадигмой программирования оболочки.
Чтобы определить результат логической операции "и", вам нужно оценить второе условие только в том случае, если первое условие выполнено - если первое условие не выполнено, общий результат всегда будет ложным.
Чтобы определить результат логической операции "или", достаточно оценить второе условие, если первое условие не выполняется - если первое условие выполняется, общий результат всегда будет истинным.
Так, в командной оболочке, если у вас есть command1 && command2
command2
будет выполнена только тогда, когда command1
завершилась и вернула код успешного результата.
Если у вас есть command1 || command2
command2
будет выполнена, когда command1
завершится, если command1
вернет код неудачи.
Другая распространенная парадигма заключается в том, что command1
является тестовой командой - это генерирует однострочный оператор if/then - например:
["$VAR" = "" ] && VAR="Значение, если пусто"
Это (длинный) способ присвоения значения переменной, если в данный момент она пуста.
Есть много примеров использования этого процесса в других местах на Stack Exchange
Несерьезный ответ, но такие проблемы иногда заставляют желать SQL -в оболочке -или, возможно, наоборот, что-то вроде:
find. -type f |
awk -F/ -vOFS=/ -vq=\' 'BEGIN{print "create table temp (dir varchar, f varchar);"}
{f=$(NF--); print "insert into temp values(" q $0 q "," q f q ");" }
END{print "select dir from temp group by dir ";
print "having sum(when f like "q"%.c"q" then 1 else 0 end)>0 ";
print "and sum(when f="q"Makefile"q" then 1 else 0 end)=1;"}
' | dosql
Используя поиск GNU, мы можем сделать это как:
find. -type f -name Makefile \
-execdir sh -c '
find. ! -name. -prune -name \*.c -execdir pwd \; -quit
' \;
При этом мы сначала ищем обычные файлы с именем Makefile, а затем, используя каталог, в котором они должны быть найдены, запускаем команду sh, которая запускает поиск только для поиска файлов.c в этом каталоге и печатает имя каталога при обнаружении первый.c, а затем быстро вышел.