bash и логическое или ||

Модератор: Модераторы разделов

Аватара пользователя
TuLiss
Сообщения: 1611
Статус: 01100
ОС: Gentoo,Ubuntu,MacOS X

bash и логическое или ||

Сообщение TuLiss »

Вопрос наверно простой, но для себя я ответа не нашел.

вот простой пример

#!/usr/bin/env bash

ls /root/ || { echo "$?"; exit 1; }
echo "test ok"

Почему условием echo "test ok" будет выполнятся если взять в фигурные скобки , все что идет после || ?

Можно сделать проверку через if then, немного другой пример

if [ ! -w "/var/data/test" ]; then
mkdir -vp "$TARGET"
if [ $? -ne 0 ]; then
echo "error creating directory"
exit 1
fi
else
echo "$TARGET - The directory already exists"
fi

но выглядит это уже громоздко, хотя оно оправдано если будет выстраиваться что то вида cmd1 && cmd2 || cmd3 (поправьте меня, если я не прав)

Второй вопрос у меня будет по переменной в переменной.

OS=debian
TARGET="/home/uZer/"$OS"_stage4"

насколько правильна такая запись или может быть лучше ""/home/uZer/"$OS"_stage4"" или "/home/uZer/${OS}_stage4" ?

Как пример вот такая запись уже становится не читаема ""$HOME"/"$OS"_stage4" , куда проще прочитать "${HOME}/${OS}_stage4" .
Чтение man'нов в слух ещЁ никому не помогало!...
kernel 4.2
chmod -x `which chmod`
War, war never changes...
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: bash и логическое или ||

Сообщение drBatty »

TuLiss писал(а):
15.04.2014 20:59
"/home/uZer/${OS}_stage4"
это правильно. Всё остальное неправильно. (но часто работает первый вариант)

TuLiss писал(а):
15.04.2014 20:59
ls /root/ || { echo "$?"; exit 1; }
echo "test ok"

TuLiss писал(а):
15.04.2014 20:59
Почему условием echo "test ok" будет
почему вы не пишете, чего ВЫ хотели? Телепаты в отпуске.

Код: Выделить всё

ls /root/
err=$?
if [ $err == 0 ]; then
  echo test ok
else
  echo ошибка №$err
  exit $err
fi

что, "громоздко"? Могу предложить компактную программу на перле, которая избавит вас от ваших проблем.

TuLiss писал(а):
15.04.2014 20:59
оно оправдано если будет выстраиваться что то вида cmd1 && cmd2 || cmd3 (поправьте меня, если я не прав)

у если вы понимаете, что

1. cmd1 выполнится всегда
2. cmd2 выполнится тогда, и только тогда, когда выполнится удачно cmd1
3. cmd3 выполнится огда, и только тогда, когда выполнится удачно cmd1 и неудачно cmd2.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: bash и логическое или ||

Сообщение SLEDopit »

drBatty писал(а):
15.04.2014 22:09
3. cmd3 выполнится огда, и только тогда, когда выполнится удачно cmd1 и неудачно cmd2.
Та ну.

Код: Выделить всё

 $ ls /dev/brain && echo wiii || echo fail
ls: cannot access /dev/brain: No such file or directory
fail
у cmd3 шансы выполниться наоборот повышаются, а не понижаются.

TuLiss писал(а):
15.04.2014 20:59
(поправьте меня, если я не прав)
конструкции if cmd1 then cmd2 else cmd3 fi и cmd1 && cmd2 || cmd3 отличаются тем, что во втором случае cmd3 имеет шанс выполниться даже в случае соблюдения условия cmd1. в конструкции с if fi это исключено. если вы это учитываете, то всё ок.

TuLiss писал(а):
15.04.2014 20:59
Как пример вот такая запись уже становится не читаема ""$HOME"/"$OS"_stage4" , куда проще прочитать "${HOME}/${OS}_stage4" .
{} тоже далеко не всегда обязательно ставить. в случае с HOME оно не нужно. а вот в OS без него никуда ( иначе за переменную будет воспринято OS_stage4 целиком.
"$HOME/${OS}_stage4" вполне годно.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
TuLiss
Сообщения: 1611
Статус: 01100
ОС: Gentoo,Ubuntu,MacOS X

Re: bash и логическое или ||

Сообщение TuLiss »

SLEDopit писал(а):
15.04.2014 23:01
{} тоже далеко не всегда обязательно ставить. в случае с HOME оно не нужно. а вот в OS без него никуда ( иначе за переменную будет воспринято OS_stage4 целиком.
"$HOME/${OS}_stage4" вполне годно.


Для home я наверно неудачно взял, так как это объявленная переменная в системе. Можно взять, что угодно.
Значит фигурные скобки допускаются ?
Просто надо помнить что

Код: Выделить всё

T="hello world"
for s in "$T"; do echo $s; done
for s in ${T}; do echo $s; done


Будет разный вывод. Это надо учитывать.

hello world
и
hello
world

Чтение man'нов в слух ещЁ никому не помогало!...
kernel 4.2
chmod -x `which chmod`
War, war never changes...
Спасибо сказали:
Аватара пользователя
TuLiss
Сообщения: 1611
Статус: 01100
ОС: Gentoo,Ubuntu,MacOS X

Re: bash и логическое или ||

Сообщение TuLiss »

SLEDopit писал(а):
15.04.2014 23:01
drBatty писал(а):
15.04.2014 22:09
3. cmd3 выполнится огда, и только тогда, когда выполнится удачно cmd1 и неудачно cmd2.
Та ну.

Код: Выделить всё

 $ ls /dev/brain && echo wiii || echo fail
ls: cannot access /dev/brain: No such file or directory
fail
у cmd3 шансы выполниться наоборот повышаются, а не понижаются.


Вот поэтому если больше двух команд
cmd1 && cmd2 || cmd3,

то лучше использовать не || , а if then. Надежнее :)

Объясните мне все же , что выполняют фигурные скобки в данном случаи ?

cmd1 || { cmd2 ; exit 1; }

drBatty писал(а):
15.04.2014 22:09
TuLiss писал(а):
15.04.2014 20:59
Почему условием echo "test ok" будет
почему вы не пишете, чего ВЫ хотели? Телепаты в отпуске.

Код: Выделить всё

ls /root/
err=$?
if [ $err == 0 ]; then
  echo test ok
else
  echo ошибка №$err
  exit $err
fi

что, "громоздко"? Могу предложить компактную программу на перле, которая избавит вас от ваших проблем.


Я не знаю, что тут непонятно ?

Почему

cmd1 || cmd2 ; exit 1;
echo "следующая команда"

неверно отрабатывается и надо писать

cmd1 || { cmd2; exit1 } ?
echo "следующая команда"

громоздко писать конструкцию, она нужна если у вас выстраивается такой cmd1 && cmd2 || cmd3
Код писать за меня не надо, вопрос не в этом.
Чтение man'нов в слух ещЁ никому не помогало!...
kernel 4.2
chmod -x `which chmod`
War, war never changes...
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: bash и логическое или ||

Сообщение drBatty »

SLEDopit писал(а):
15.04.2014 23:01
у cmd3 шансы выполниться наоборот повышаются, а не понижаются.
ага. Вероятностное программирование.

Но в целом, да, согласен. Я просто такой быдлокод никогда не пишу. Но может кому-то и нравиться...

TuLiss писал(а):
16.04.2014 09:10
Значит фигурные скобки допускаются ?

для переменных можно ставить, а можно не ставить. Как хотите.

Обязательно _нужно_ ставить скобки в ${X}Y тогда, и только тогда, когда Y это буква, цифра, или "_". Но если сомневаетесь, то лучше поставьте. ИМХО со скобками читать легче.

TuLiss писал(а):
16.04.2014 09:10
for s in "$T"; do echo $s; done
for s in ${T}; do echo $s; done


Будет разный вывод. Это надо учитывать.

при чём тут скобки-то? В первой строке есть кавычки, а во второй их нет. Потому и по разному.

TuLiss писал(а):
16.04.2014 10:27
то лучше использовать не || , а if then. Надежнее

гвоздь забитый молотком сидит надёжнее, чем гвоздь закрученный отвёрткой.

TuLiss писал(а):
16.04.2014 10:27
что выполняют фигурные скобки в данном случаи ?

cmd1 || { cmd2 ; exit 1; }

а что значит ☣ в моих постах?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
bormant
Сообщения: 1354

Re: bash и логическое или ||

Сообщение bormant »

TuLiss писал(а):
16.04.2014 10:27
Объясните мне все же , что выполняют фигурные скобки в данном случаи ?
Они всем показывают, что man bash не читан. А между тем там:
{ список; }
Список выполняется в среде текущего командного интерпретатора. Список должен завершаться переводом строки или точкой с запятой.
Эту команду называют командой группировки. Статусом возврата является статус выхода списка.
Спасибо сказали:
Аватара пользователя
TuLiss
Сообщения: 1611
Статус: 01100
ОС: Gentoo,Ubuntu,MacOS X

Re: bash и логическое или ||

Сообщение TuLiss »

bormant писал(а):
16.04.2014 14:03
TuLiss писал(а):
16.04.2014 10:27
Объясните мне все же , что выполняют фигурные скобки в данном случаи ?
Они всем показывают, что man bash не читан. А между тем там:
{ список; }
Список выполняется в среде текущего командного интерпретатора. Список должен завершаться переводом строки или точкой с запятой.
Эту команду называют командой группировки. Статусом возврата является статус выхода списка.



Вот за это спс. Видно я это просто проморгал.

drBatty писал(а):
16.04.2014 10:48
при чём тут скобки-то? В первой строке есть кавычки, а во второй их нет. Потому и по разному.

TuLiss писал(а):
16.04.2014 10:27
то лучше использовать не || , а if then. Надежнее

гвоздь забитый молотком сидит надёжнее, чем гвоздь закрученный отвёрткой.



В первой строке есть кавычки, но нет фигурных скобок. Во второй есть фигурные скобки, кавычек нет.
Поэтому ответ и разный - это хороший ответ. Ваш КО.

Вот вы зря так, я тут сделал поиск по примера - и вот попадаются авторы с
echo "hello world!"
Чтение man'нов в слух ещЁ никому не помогало!...
kernel 4.2
chmod -x `which chmod`
War, war never changes...
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21497
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: bash и логическое или ||

Сообщение Bizdelnick »

TuLiss писал(а):
16.04.2014 14:18
В первой строке есть кавычки, но нет фигурных скобок. Во второй есть фигурные скобки, кавычек нет.
Поэтому ответ и разный - это хороший ответ. Ваш КО.

От наличия/отсутствия фигурных скобок ничего бы в данном случае не изменилось. Ответ разный именно из-за кавычек.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: bash и логическое или ||

Сообщение SLEDopit »

TuLiss писал(а):
16.04.2014 10:27
то лучше использовать не || , а if then. Надежнее
Дело не в надёжности, а в том, какой результат преследуются. Иногда if fi не годится, а нужно именно && && || .
TuLiss писал(а):
16.04.2014 10:27
Почему

cmd1 || cmd2 ; exit 1;
echo "следующая команда"

неверно отрабатывается и надо писать
Отрабатывается она как написано. Просто вы ожидаете не тот результат. Впрочем про {} уже объяснили. Можно ещё использовать конструкцию cmd1 || cmd2 && exit 1 , но exit 1 может не сработать, если cmd2 свалится с ошибкой.

TuLiss писал(а):
16.04.2014 14:18
В первой строке есть кавычки, но нет фигурных скобок. Во второй есть фигурные скобки, кавычек нет.
Поэтому ответ и разный - это хороший ответ. Ваш КО.
Ответ совершенно верный между тем. Кавычки экранируют пробелы и прочие разделители и они не игнорируются for'ом. Когда кавычек нет, то пробел воспринимается как разделитель и hello обрабатывается отдельно от world. А наличие фигурных скобок на результат не влиет.

upd. Что-то я долго писал ответ..
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: bash и логическое или ||

Сообщение drBatty »

TuLiss писал(а):
16.04.2014 14:18
В первой строке есть кавычки, но нет фигурных скобок. Во второй есть фигурные скобки, кавычек нет.
Поэтому ответ и разный - это хороший ответ. Ваш КО.

повторяю, {скобки} тут не при чём, и на результат НЕ влияют. Вывод разный из-за кавычек.
TuLiss писал(а):
16.04.2014 14:18
Вот вы зря так, я тут сделал поиск по примера - и вот попадаются авторы с

$

$ cat >t echo "hello world!" $ bash t hello world!


УМВР, ЧЯДНТ?

SLEDopit писал(а):
16.04.2014 14:29
Иногда if fi не годится, а нужно именно && && || .

пример?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: bash и логическое или ||

Сообщение SLEDopit »

drBatty писал(а):
17.04.2014 22:01
пример?

Код: Выделить всё

download file && process file && send file to remote || echo file skipped
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: bash и логическое или ||

Сообщение drBatty »

SLEDopit писал(а):
17.04.2014 22:37
download file && process file && send file to remote || echo file skipped

и почему это нельзя оформить например функцией с if и return?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: