Използвам GNU xargs (версия 4.2.2) в паралелен режим и изглежда, че надеждно губя изход при пренасочване към файл. При пренасочване към тръба изглежда, че работи правилно.
Следните команди на обвивката демонстрират минимален, пълен и проверим пример за проблема. Генерирам 2550 числа, като използвам xargs
, за да го разделя на редове от по 100 аргумента, всеки общо 26 реда, където 26-ият ред съдържа само 50 аргумента.
# generate numbers 1 to 2550 where each number is on its own line
$ seq 1 2550 > /tmp/nums
$ wc -l /tmp/nums
2550 /tmp/nums
# piping to wc is accurate: 26 lines, 2550 args
$ xargs -P20 -n 100 </tmp/nums | wc
26 2550 11643
# redirecting to a file is clearly inaccurate: 22 lines, 2150 args
$ xargs -P20 -n 100 </tmp/nums >/tmp/out; wc /tmp/out
22 2150 10043 /tmp/out
Вярвам, че проблемът не е свързан с основната обвивка, тъй като обвивката ще извърши пренасочването преди изпълнението на командите и ще изчака xargs да завършат. В този случай предполагам, че xargs завършва преди прочистване на буфера. Въпреки това, ако моята хипотеза е вярна, не знам защо този проблем не се проявява при писане в канал.
Редактиране:
Появява се при използване на >>
(създаване/добавяне към файл) в обвивката, проблемът не изглежда да се проявява:
# appending to file
$ >/tmp/out
$ xargs -P20 -n 100 </tmp/nums >>/tmp/out; wc /tmp/out
26 2550 11643
# creating and appending to file
$ rm /tmp/out
$ xargs -P20 -n 100 </tmp/nums >>/tmp/out; wc /tmp/out
26 2550 11643
Shell> wc -l /tmp/nums 2550 /tmp/nums Shell> xargs -P20 -n 100 </tmp/nums | wc 26 2550 11643 Shell> xargs -P20 -n 100 </tmp/nums >/tmp/out; wc /tmp/out 26 2550 11643 /tmp/out Shell>
- person Sriharsha Kalluru   schedule 08.09.2015>>
вместо>
пренасочване? Ако е така, има някакво обяснение. - person Jonathan Leffler   schedule 08.09.2015>>
проблемът не се проявява. Опитах се да създам файла преди време и да пренасоча, като използвам и използвам „›“ (съкращавам съществуващия файл) и проблемът изглежда се появява отново. - person snap   schedule 08.09.2015>
, какви числа се появяват в началото на/tmp/out
? Дали са числа като 1, 2, 3 или са числа като 2001, 2002, 2003? Имам някои проблеми с намирането на правдоподобен механизъм за проблема. Поведението на канала и добавянето е достатъчно лесно за обяснение. Но поведението с>
трябва да е по същество същото и оставам да се чудя как нещата се развалят. Имате ли наличниtruss
илиstrace
? Ако е така, може да е поучително да погледнете какво прави процесътxargs
(но не — поне на първо място — какво правят неговите деца). […продължение…] - person Jonathan Leffler   schedule 08.09.2015xargs.log
, след като стартиратеstrace -o xargs.log xargs -P 20 -n 100 </tmp/nums > /tmp/out
? Мисля за нещо катоlseek()
на файлов дескриптор 1, но не съм сигурен колко правдоподобно е това. Един от проблемите може да е, че всъщност е дете, което причинява пакостите; в такъв случай ще трябва да използвате опцията „следване на деца“ (-f
), за да видите какво причинява проблема. Но резултатът би бил много по-обемист. Получавам „правилния“ изход както на Mac OS X 10.10.5, така и на Ubuntu 14.04 LTS (работещ във VM под Mac OS X). - person Jonathan Leffler   schedule 08.09.2015strace
. Сега анализирам изхода. Проблемът се случва в Ubuntu 14.04 LTS (също във виртуална машина), но забелязах, че е по-очевиден на някои системи в сравнение с други. Намирам, че проблемът възниква бързо в груб цикъл while:seq 1 2550 > /tmp/nums; while true; do xargs -P20 -n 100 </tmp/nums >/tmp/out; wc /tmp/out; done | grep -v ' 26 '
. Опитах това на OSX 10.10.4 и не успях да изявя и този проблем. [1/2] - person snap   schedule 08.09.2015xargs
родителски процес, който се отделя от децата, излизайки рано, докато дете (което наследява и пише в stdout) не изчиства буфера. Ще прегледам изхода на strace, за да видя дали мога да определя къде се случва това. [2/2] - person snap   schedule 08.09.2015