Разъяснение относительно поведения сценария оболочки наряду с каналом

Из страницы справочника крона:

При выполнении команд любой вывод отправляется по почте владельцу crontab (или пользователю, названному в переменной среды MAILTO в crontab, если такой существует). Дочерним копиям крона, выполняющего эти процессы, принудили их имя к верхнему регистру, как будет замечен в системном журнале, и PS произвел.

Таким образом, необходимо проверить Ваш/корень почту или системный журнал (например,/var/log/syslog).

4
17.11.2018, 22:04
2 ответа

Вы путаете аргументы и стандартный вход. Передача по каналу данных к программе не эквивалентна предоставлению его параметры командной строки.

В Вашем первом случае Вы не передаете аргументов своему сценарию, только подавая его данные через его стандартный входной поток. Так $1 сброшен на целое время сценария.
Первый вызов more таким образом не имеет никакого параметра и разбивает на страницы стандартный вход. Это отображает то, что Вы передали по каналу там (dir1, как текст). Последующее echo только печатает новую строку, так как это не заставляет ничего печатать, и последнее more не имеет ничего больше для печати любого - стандартный вход был "истощен" первым.

Во втором случае Вы действительно передаете аргумент. Так $1 имеет значение dir2 в сценарии. То же самое происходит, за исключением того, что первое more оба:

  • пролистывает оба стандартных входа
  • попытки разбить на страницы файл dir2 и ошибки, так как это - каталог

Эхо делает то, что ожидается, учитывая, что $1 содержит dir2, и последнее more только ошибки на dir2 - это не имеет ничего для чтения из стандартного входа.

7
27.01.2020, 20:47
  • 1
    Спасибо за разъяснение. В моем случае и dir1 и dir2 являются каталогами. То, почему параметр прибывает из канала, рассмотрело строку, но тот передал как аргумент, который рассматривают как каталог и ошибки? –  Manoj 07.05.2013, 10:35
  • 2
    Нет никакого параметра, прибывающего из канала. Стандартный входной поток не обеспечивает параметры. more пролистывает стандартный вход, не интерпретируя это, если Вы даете ему что-то на стандартном входе. Это не смотрит на dir1 вообще в любом случае, это просто печатает его дословно. –  Mat 07.05.2013, 10:38
  • 3
    Теперь это ясно!Спасибо! Таким образом, я предполагаю, что единственный способ передать данные от канала в сценарий состоит в том, чтобы использовать эхо dir1 | xargs, колотят script.sh. –  Manoj 07.05.2013, 11:09
  • 4
    Зависит от того, что Вы пытаетесь сделать точно. Можно использовать read встроенный для обработки данных от стандартного входа или других файлов также. –  Mat 07.05.2013, 11:11

Различие находится в "Аргументах" VS "Стандартный Вход".

Когда Вы работаете echo dir1 | bash script.sh, $1 аргумент в Вашем script.sh всегда пусто, поскольку никакой аргумент не дан ему (попытайтесь добавить a set -x при начинании и Вы будете видеть его в выводе отладки). dir1 то, которое отражено, прибывает из стандартного входа как more управляйте читает stdin, если никакой аргумент не дан (помнить $1 пусто).

Как cmd1 | cmd2 работы

При использовании канала:

  1. cmd2 подпроцесс cmd1.
  2. stdin cmd2 "включается" на stdout cmd1.

Поскольку Linux stdio lib предложил буферизированный поток через дескриптор файла, stdin содержание будет использовано (т.е. только для чтения однажды) только, когда stdin будет открыт.

Шаг за шагом cmd1 | cmd2 рабочий процесс

Команда Example:

echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")

  1. echo dir1 | : запишите"dir1\n"на stdout первой команды, которая не отражена, но буферизована через stdio и доступная для подобрабатывания через stdin.
  2. echo "a" : запишите"a\n"на stdout; не читает stdin! так"dir1\n"строка все еще доступна
  3. read stdinvalue : считайте stdin до EOL (или EOF), и хранит строку в переменной удара
  4. echo "$stdinvalue" : запишите stdinvalue значение переменной в stdout
4
27.01.2020, 20:47

Теги

Похожие вопросы