1

*** Оставлю это здесь не ради темы, а в качестве заметки bx
Поэтому попрошу холиварню здесь не разводить, ну а если есть чем еще дополнить - welcome =)
***


Объединение команд это очень полезная операция которую я сам очень часто применяю в терминале.
Допустим вам нужно куда-то срочно уйти, но вы хотите скомпилировать что-либо. Вы знаете, что сначала нужно ввести # ./configure потом # make и только потом # make install, при том окончание работы make иногда приходиться ждать час, а то и поболее. В таких моментах придет на помощь объединение команд.
Зная этот прием, вы введете # ./configure && make && make install и уйдете по своим делам в то время как все нужные команды выполняться сами и полностью завершат компиляцию.
Можно даже добавить команду shutdown -h now в конец для отключения компьютера после выполнения всех операций.


*** Последовательное выполнение команд вне зависимости от исхода работы предыдущей. [ ; ] ***Выполнить сколько угодно команд последовательно можно путем разделение команд символом ; (точка с запятой).
Пример: # ./configure ; make ; make install -выполнятся все команды последовательно вне зависимости от исхода предыдущих.
То есть, если в ./configure будет выведено сообщение об ошибки, то интерпретатор все равно попробует выполнить make и make install.


*** Последовательное выполнение команд при условии успешного завершения предыдущих. [ && ] ***Символы && (два амперсанда) позволяют выполнять действие подобные предыдущей конструкции, но при не успешном завершении команды интерпретатор прекратит выполнение всего сценария.
Например: # ./configure && make && make install -если в ./configure будет ошибка, то последующие команды не будут исполняться. Если же все прошло удачно, то начнут выполняться make и make install притом если в make будет ошибка, то make install выполняться тоже не будет.


*** Выполнение команды, если предыдущая завершилась ошибкой. [ || ] ***Можно выполнить команды не только при успешном завершении предыдущей, но и при ошибочном завершении предыдущей с помощью символов || (две прямых черты).
Пример: # make install || echo 'Ошибка!' -выведется слово ошибка при неудачном завершении команды make install, иначе это слово выводиться не будет.


*** Использование выходных данных одной команды при вызове другой. [ $() ] [ ` ` ] ***Давайте посмотрим на пример: # touch $(uname -r)
Эта команда создаст файл имя которого будет версия текущего ядра linux.
Команде touch передается с помощью конструкции $() команда выходные данные которой можно использовать для аргумента первой команды.
Это можно записывать в другой форме, иногда так бывает удобнее: # touch `uname -r`*** Только кавычки здесь должны быть те, который на букве 'Ё', крайне слева вверху. ***


*** Запись результатов выполнения команды в файл. [ > ] ***Это очень удобная функция! С помощью символа > (больше) можно записать вывод команды в текстовый файл.
Пример: # ls -R /home > home.txt -эта команды запишет в файл home.txt все папки и файлы находящиеся в домашнем каталоге и подкаталогах. В стандартный вывод ничего не выведется - все пойдет исключительно в файл.
Иногда для этого приходится указывать явно номер файлового дескриптора вывода: 1 - SYSOUT, 2 - SYSERR
Записать сообщения об ошибках в файл: # xxx 2>home.txt
Объединить вывод программы с сообщениями об ошибках, и всё вместе это отправить в файл: # xxx 2>&1 >home.txt*** В такой записи & - обязателен, это специальная синтаксическая форма ... иначе ошибки бы записывались в файл с именем "1". ***


*** Использование дозаписи [ >> ] ***Чтобы файл не очищался, а новые данные добавлялись в конец надо использовать символы >> (два знака больше)
Пример: # ls >> home.txt -при всех последующих вызовах такой команды новые данные будут добавляться в конец файла.

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

2 (15.03.2017 10:20:19 отредактировано Olej)

DiabloPC пишет:

Давайте посмотрим на пример:
# touch $(uname -r)

Это можно записывать в другой форме, иногда так бывает удобнее:

 Консоль:
$ touch `uname -r`

Только кавычки здесь должны быть те, который на букве 'Ё', крайне слева вверху.


Olej, Добавил в шапку.

3

Olej, В курсе =) Но никак не пойму в чем удобство? Как по мне то вариант  [ $() ] более, даже не знаю как обозвать... более наглядный, чтоль...
По крайней мере мне его удобнее пользовать... А результат, собственно тот-же bx
ЗЫ
А еще в этом варианте можно завернуть вот так: [ $( $() ) ], а с кавычками такое не прокатит.

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

4

DiabloPC пишет:

Пример:
# ls -R /home > home.txt -эта команды запишет в файл home.txt

Иногда для этого приходится указывать явно номер файлового дескриптора вывода: 1 - SYSOUT, 2 - SYSERR

Записать сообщения об ошибках в файл:

 Консоль:

$ xxx 2>home.txt

Объединить вывод программы с сообщениями об ошибках, и всё вместе это отправить в файл:

 Консоль:

$ xxx 2>&1 >home.txt

В такой записи & - обязателен, это специальная синтаксическая форма ... иначе ошибки бы записывались в файл с именем "1".
*** Добавлено: 15.03.2017 10:36:20 ***

DiabloPC пишет:

# ./configure ; make ; make install -выполнятся все команды последовательно вне зависимости от исхода предыдущих.

Если говорить о последовательном выполнении, то нужно бы, для сравнения, упомнить и о конвейерах - параллельном выполнении программ:

 Консоль:

$ prog1 | prog2 | prog3
 
Здесь:
- в отличие от ';' prog1, prog2, prog3 выполняются параллельно, одновременно...
- выход (SYSOUT) каждого процесса (кроме последнего) замыкается на вход (SYSOUT) предыдущего.

5

DiabloPC пишет:

Последовательное выполнение команд вне зависимости

Это лишь более компактная запись трех команд в одной строке. В скриптах лучше такого избегать для повышения читабельности.
*** Добавлено: 15th Mar 2017 10:42:34 ***

Olej пишет:

prog1 | prog2 | prog3

Результат работы первой команды передается на стандартный ввод (stdin) второй программы, а результат работы второй передается на stdin третьей. Это называется pipe ("труба").

Истинный hotplug - это обычная электрическая розетка: воткнул - работает, и никаких драйверов.
Arch Linux/Xfce/Xiaomi Mi Notebook Pro 15.6 | Slackware64-current/Xfce/Lenovo G580

6

yars, В скриптах - понятно что лучше так не делать.. Там строчек много, можно и в разных, по человечески, написать. А это именно для командной строки применимо, собственно все началось с того что решил кинуть слив бэкапа и пойти спать, но с учетом того что бэкапы я делаю с помощью dd_rescue --sparse нужно было предварительно забить свободное пространство на диске нулями, что само по себе дело не очень быстрое, и только потом запускать копирование даных. Самый простой способ сделать это - dd_rescue /dev/zero /zerofile && rm /zerofile, но тут встал вопрос: && ведь обрывает цепочку при ошибках в завершении предыдущей команды. Блин, а как сделать чтобы оно продолжило выполнять все остальное? Ну не пользовал я это никогда. Ну ессно гуголь в помощь, но, как ни странно, на это ушло гараздо больше времени чем я предполагал. Вот и решил тут оставить, дабы всегда под рукой было, ну и мож еще кому пригодится =)

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

7

yars пишет:

Это называется pipe ("труба").

В русскоязычной литературе это называется "конвейер".
Но важное здесь, что подчеркнуть нужно, что prog1, prog2, prog3 здесь выполняются параллельно.

8

DiabloPC пишет:

амый простой способ сделать это - dd_rescue /dev/zero /zerofile && rm /zerofile, но тут встал вопрос: && ведь обрывает цепочку при ошибках в завершении предыдущей команды.

Эмм... а такой вараинт разве не парокатит?
dd_rescue /dev/zero /zerofile ; rm /zerofile
В любом случае выполнисят 2я команда после завершения первой

It is good day to die ...
MS Windows 10
Заметки о главном...

9

Olej пишет:

конвейерах - параллельном

Ну немного разные понятия.

В конвеере они выполняются последавательно, передавая STDOUT, на STDIN следующей програмы.

А паралельно они выполняются через & (в фоновом режиме) >> # prog1 & prog2 & prog3
*** Добавлено: 15th Mar 2017 9:55:03 am ***

i2ks пишет:

Эмм... а такой вараинт разве не парокатит?

Так в том то и дело что прокатит, вот только никогда не пользовался - пришлось искать как это делается. )) Как-то так сложилось что всегда пользовал цепочки только с удачным завершением bx

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

10

DiabloPC пишет:

В конвеере они выполняются последавательно,

В конвейере программы выполняются параллельно.

11

Olej пишет:

В конвейере программы выполняются параллельно.

Как они могут выполняться параллельно если каждая последующая команда ждет результатов работы предыдущей?

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

12

DiabloPC пишет:

Как они могут выполняться параллельно

Вот так bf

DiabloPC пишет:

если каждая последующая команда ждет результатов работы первой?

Никто никого не ждёт.

13

Olej, 

+ вот довольно наглядно показано выполнение конвеера. И где же здесь параллельность?

https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Process_output_chaining_via_pipes.ru.svg/584px-Process_output_chaining_via_pipes.ru.svg.png

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

14 (15.03.2017 11:36:24 отредактировано Olej)

DiabloPC пишет:

В конвеере они выполняются последавательно, передавая STDOUT, на STDIN следующей програмы.

Ну как же так? ai
Вы таки сами себе так сильно противоречите (как сказали бы в Одессе):
- если бы процессы выполнялись последовательно...
- то при выполнении предыдущей - ещё нет никакого STDIN последующей ... некуда ничего передавать...
- а после завершения предыдущей - уже нет никакого STDOUT, он уже закрыт и ликвидирован ... откуда передавать.

Конвейеры в коде реализуются через POSIX API pipe, который может работать только между родственными параллельными процессами.
*** Добавлено: 15.03.2017 11:21:03 ***

DiabloPC пишет:

Olej,

Учи матчасть! bd

*** Добавлено: 15.03.2017 11:23:16 ***

DiabloPC пишет:

В конвеере они выполняются последавательно, передавая STDOUT, на STDIN следующей програмы.

А та глупость, которую вы имеете в виду, записывалась бы так:

 Консоль:

$ prog1 >xxx ; prog2 <xxx

DiabloPC пишет:
+ вот довольно наглядно показано выполнение конвеера. И где же здесь параллельность?

 Консоль:

[olej@dell 14]$ cat | tee x | tee y
...

 Консоль:

[olej@dell own_LSD2_12]$ ps -A | tail -n30
...
10150 pts/2    00:00:00 cat
10151 pts/2    00:00:00 tee
10152 pts/2    00:00:00 tee
10189 pts/11   00:00:00 ps
10190 pts/11   00:00:00 tail
...

Как легко видеть, это скопировано из выполняющихся терминалов ... а не пересказано от большого ума. az

15

Olej пишет:

Учи матчасть!

Походу прийдется =)

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

16 (15.03.2017 12:31:47 отредактировано Olej)

DiabloPC пишет:

Походу прийдется =)

Зачем же вы удалили приводимый вами пример?
Пример, по-моему, как-раз был хорош.

P.S. Как-раз синтаксис командной строки shell/bash стоило бы упорядочить и свести в краткую внятную справку, потому что это вещь хуже всего описанная по учебникам, и по которой трудно найти справку в поисковиках ... потому что непонятно что писать в контекст поиска.

17

Olej пишет:

Пример, по-моему, как-раз был хорош.

Неособо.... Там, если вдуматься в логику работы получается немного не то...

 Консоль:
echo $i | grep -E [0-9] && sleep1
Здесь получается pipe, затем, после успешного выполнения одного прохода, он завершается и выполняется sleep, а затем создается новый конвеер....
...по идее так....
*** Добавлено: 15th Mar 2017 11:35:37 am ***

Olej пишет:

непонятно что писать в контекст поиска

вотЬ вотЬ, собственно из-за этого у меня минут 20 и занял поиск того что в шапке  be
*** Добавлено: 15th Mar 2017 11:41:40 am ***

Olej пишет:

Как легко видеть, это скопировано из выполняющихся терминалов ... а не пересказано от большого ума.

Вот, придумал как сделать более наглядный пример параллельности в цикле:

 Консоль:
for i in 1 2 3 4 5; do $(echo echo $i; sleep 1) | grep -E [0-9]; done

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

18

DiabloPC пишет:

Вот, придумал как сделать более наглядный пример параллельности:

http://www.gnu.org/software/parallel/ наглядней не бывает :-)

It is good day to die ...
MS Windows 10
Заметки о главном...

19

i2ks пишет:
DiabloPC пишет:

Вот, придумал как сделать более наглядный пример параллельности:

http://www.gnu.org/software/parallel/ наглядней не бывает :-)

Да нет - это совершенно о другом:

GNU parallel is a shell tool for executing jobs in parallel ...


Это об отдельной частной утилите, никакого отношения к обсуждаемой теме не имеющей.

20

Olej пишет:

Да нет - это совершенно о другом:

я к тому, то что можно посмотреть как там это реализованно.
Там же все на перле на скольо я вижу.

It is good day to die ...
MS Windows 10
Заметки о главном...

21 (15.03.2017 15:06:43 отредактировано Olej)

i2ks пишет:

я к тому, то что можно посмотреть как там это реализованно.

Зачем? (посмотреть) ap
Мне, как и всякому, кто минимально знает программирование C, POSIX API, fork() и т.д. - это и так абсолютно прозрачно.
А тем, кто не знает C-программирование и POSIX ... остаётся только поверить на слово. aw

GNU parallel is a shell tool for executing jobs in parallel using one or more computers.

В теримнологии shell & UNIX такие вещи как process (программа, утилита, ...) и job - это принципиально разные вещи.

22

Olej пишет:

В теримнологии shell & UNIX такие вещи как process (программа, утилита, ...) и job - это принципиально разные вещи.

Да это и так понятно, одно следует из другого. это я про процессы и задания.

It is good day to die ...
MS Windows 10
Заметки о главном...

23

Olej пишет:

touch `uname -r`

Olej пишет:

xxx 2>home.txt
$ xxx 2>&1 >home.txt

Закинул наверх

- Пап, а вирусы под линукс есть?
- Есть, но всего 5, и их сначала нужно откомпилировать под свою систему, дать права на запуск и запустить.
Как сделать и разместить скриншот || Прежде чем создавать тему

24

DiabloPC пишет:
Olej пишет:

touch `uname -r`

Olej пишет:

xxx 2>home.txt
$ xxx 2>&1 >home.txt

Закинул наверх

На самом деле для отправки stdout и stderr в файл достаточно

 Консоль:
$ xxx &>home.txt