Недетерминированное поведение Grep в сочетании с Подробнее

273
bers

Что бы вы ожидали после этого:

for /l %i in (1,1,100) do @more some.bbl | grep a | md5sum 

Скорее всего, не это:

ec3ecb76408d4225ff23a25d0596e00f *- 13cfd899b90b9cd7aedb406a785e8eac *- 737e8898a65657f1a2ce8012ff1ffe82 *- d4095243e56a7da3b31a352423a5417a *- 319db7810e677414ca1609238bdeba6f *- 31e626a8ce0732fda1fa7499c8b13dfa *- 006fe390f923d50348d65d0bbefa64d8 *- 77708f62cb2d61a45788a656d0979aee *- cda10a9ab71c2bce4df069c479241349 *- b01b71dc7dca11808ca989c4985513ca *- c22a6f8b1cac9a93c4fe10b07a9f483a *- 0b04f4b24f3f183270eb7414f4f86e3d *- 5a2f8b8ad482ae8f70b7ce3384a7c9e2 *- beccdbe737b48c02b48c4524cd89eede *- a16fec5238cfe8dfff6b403ff943a8ca *- ec0cd2edc0009abd14119915a8b563f4 *- 1e78f0012ca09aeade169f815415da40 *- ... 

Я тоже волновалась, поэтому я провела пару проверок вменяемости:

for /l %i in (1,1,100) do @more some.bbl | md5sum 

дает 100 раз

ace4f37f3a1433e29696a535c0b79f2c *- 

То же самое для

for /l %i in (1,1,100) do @grep a some.bbl | md5sum 

а также

d8753d755025a1119cd2910c6f5cb0de *- 

Так что more, grepи md5sumотлично работают сами по себе. Кроме того, труба перед md5sumне является проблемой, так как

for /l %i in (1,1,100) do @more some.bbl | grep a > out%i md5sum out* 

подтверждает проблему. fcПо выводам я не вижу разницы. diffпри их использовании обнаруживаются невидимые различия, подтвержденные шестнадцатеричным редактором как различия в окончаниях строк в, казалось бы, случайных местах (и отличающихся от файла к файлу).

Проблема все еще видна, но не так часто, в этом примере:

for /l %i in (1,1,100) do @more some.bbl | grep "[a-z]" | md5sum 

получая

b135bcfe0bcfb7f1c43fe1905164c31e *- b135bcfe0bcfb7f1c43fe1905164c31e *- b135bcfe0bcfb7f1c43fe1905164c31e *- b135bcfe0bcfb7f1c43fe1905164c31e *- ef23817185d41987c11cb1fc4371bb76 *- b135bcfe0bcfb7f1c43fe1905164c31e *- b135bcfe0bcfb7f1c43fe1905164c31e *- b135bcfe0bcfb7f1c43fe1905164c31e *- e398e63b60cee3e271967f01350068f1 *- b135bcfe0bcfb7f1c43fe1905164c31e *- b135bcfe0bcfb7f1c43fe1905164c31e *- b135bcfe0bcfb7f1c43fe1905164c31e *- ... 

Теперь у меня заканчиваются идеи, в чем причина. Мне было бы все равно, если бы я не потерял ни одной действительной строки в таких случаях:

for /l %i in (1,1,100) do @more "some.bbl" | grep "\}$" | wc -l 

Это дает

249 249 249 248 255 253 252 248 251 ... 

Чтобы воспроизвести похожие проблемы, вы можете использовать этот файл

for /l %i in (1,1,200) do @echo XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX>> some.bbl 

Еще немного информации

C:\>ver  Microsoft Windows [Version 6.1.7601]  C:\>more /h  Displays output one screen at a time.  MORE [/E [/C] [/P] [/S] [/Tn] [+n]] < [drive:][path]filename ...  C:\>grep --ver  GNU grep 2.6.3  Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  C:\>md5sum --ver  md5sum (GNU coreutils) 8.15 Packaged by Cygwin (8.15-1) Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  Written by Ulrich Drepper, Scott Miller, and David Madore. 

Почему это происходит?

Обновление: проблема также уходит, заменяя moreэто cat:

C:\>cat --ver  cat (GNU coreutils) 8.15 Packaged by Cygwin (8.15-1) Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  Written by Torbjörn Granlund and Richard M. Stallman. 
1
Почему вы используете больше таким образом и чего именно вы пытаетесь достичь? qasdfdsaq 9 лет назад 0
Я не помню, почему я изначально использовал «больше». Я заметил, однако, что в некоторых случаях `больше | grep` быстрее чем `grep`. В любом случае, разве не совершенно неважно, почему я использую `more '(а не` cat`, `grep` или что-то еще) в отношении моего вопроса, ПОЧЕМУ комбинация инструментов командной строки ведет себя недетерминированно? путь? bers 9 лет назад 0
Я думаю, что это актуально, потому что больше не предназначено для использования таким образом. Я предполагаю, потому что вы используете больше таким образом, что он не предназначен для функционирования, он разветвляется или возвращается в неправильное время, или неправильно определяет параметры вашего терминала, потому что нет терминала. Я не удивлюсь, если программа ведет себя недетерминированно, когда задокументированное поведение «неопределено» qasdfdsaq 9 лет назад 0
Ой. Таким образом, вы думаете, что тот факт, что «more» ожидает, что ввод терминала в конце экрана (когда вывод не перенаправлен) может повлиять на вывод? И кажущаяся случайность в основном является результатом положения в окне виртуального терминала? Это может иметь смысл. bers 9 лет назад 0

0 ответов на вопрос