Странные результаты тройного подключения к STDOUT & tee / dev / null> ( wc -l> tmp.txt) & конвейер снова встраивает `cat tmp.txt`

В общем случае это невозможно. Абсолютного смещения (в определенный момент времени) плюс флаг летнего времени недостаточно для указания конкретного часового пояса. У вас нет никакой информации о том, когда начинается и заканчивается переход на летнее время. Вы даже не можете точно знать, действует ли сейчас летнее время.

Если вас интересует только смещение UTC в определенный момент времени, то оно у вас уже есть.

Если вам нужно вычислить смещение UTC в произвольные другие моменты времени, вам нужна дополнительная информация — в идеале фактическое (Олсон) название часового пояса.

1
12.12.2016, 03:23
1 ответ

Как AlexP объяснил в комментариях, команды в конвейере выполняются параллельно . Вы, кажется, уверены, что это не так; пожалуйста, забудьте это заблуждение, вы не сможете понять, что происходит, пока не откроете свой разум.

Поскольку процессы выполняются параллельно, последовательность операций зависит от точного времени и может не воспроизводиться от одного запуска к другому.

В вашем первом примере следующие команды выполняются параллельно:

  • seq 1 12773
  • tee / dev / null
  • wc -l> tmp.txt (замена процесса также создает канал и выполняет команду параллельно)
  • head - $ ((0x`openssl rand -hex 7`% `cat tmp.txt` + 1)) - это включает три разные команды и head запускается после выхода из openssl и cat
  • tail -1

Поскольку wc -l> tmp.txt и cat tmp.txt запускается параллельно, это непредсказуемо, когда cat tmp.txt будет выполняться в соответствии с выводом из wc :

  • Он может выполняться до того, как будет выполнено перенаправление на tmp.txt , и либо забрать файл из предыдущий запуск, если он есть, или пожаловаться, что в противном случае файл не существует.
  • Он может выполняться после выполнения перенаправления, но до того, как wc произведет какой-либо вывод; в этом случае файл пуст, поскольку перенаправление усекает файл.
  • Он может выполняться, пока wc производит вывод, и захватывать только начало вывода. В большинстве систем wc производит свой вывод атомарно (потому что он такой короткий), поэтому этого не произойдет.
  • Он может выполняться после того, как wc завершит создание вывода.

Экспериментально я получаю те же результаты, что и вы (на машине Linux с ядром 3.16, которая в остальном в основном простаивает): с seq 1 12773 , cat tmp.txt подбирает вывод wc ; с seq 1 12774 , cat tmp.txt забирает пустой файл. Так почему же существует разница между 12773 и 12774, но результаты довольно надежны ниже этого значения?

$ seq 1 12774 | wc -c
65538

Существует порог в 65536 байт, и это значение представляет собой емкость буфера канала . Команда head… запускается медленно, потому что сначала она должна выполнить до завершения openssl и cat . При запуске предыдущая команда конвейера записывается в буфер канала. Когда буфер канала заполняется, предыдущая команда должна остановиться.При числах до 12773 буфер канала никогда не заполняется, поэтому, по всей вероятности, seq завершит работу до openssl (у него намного меньше работы) и wc успевает написать свой вывод.Но с числами больше 12774 буфер канала заполняется; поэтому tee застрял при записи в вывод, который идет в head… , и еще не завершает запись вывода в wc . Тем временем cat работает с пустым файлом.

Когда вы добавляете больше труб, у каждой есть свой буфер, поэтому остается больше места до тройников киосков.

0
28.01.2020, 01:06

Теги

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