yuri.nefe...@gmail.com -> debian-russian @ Wed, 30 Nov 2016 19:49:58 +0300 (MSK):
>> Доброго времени суток. >> >> В shell скрипте обрабатывается список в котором в качестве разделителя >> используется нулевой символ '\0'. Вроде совместимо с POSIX, но нужное >> поведение есть только в zsh. В bash и dash ведет себя неправильно. >> >> Код ------------------------------------------------------------------- >> IFS=$(printf '\0') >> for i in $(seq 1 10 | tr '\n' '\0') >> do >> echo "i = $i" >> done >> >> Вывод ----------------------------------------------------------------- >> zsh /tmp/list.sh >> i = 1 >> i = 2 >> i = 3 >> i = 4 >> i = 5 >> i = 6 >> i = 7 >> i = 8 >> i = 9 >> i = 10 >> i = >> >> bash /tmp/list.sh >> i = 12345678910 >> >> dash /tmp/list.sh >> i = 12345678910 >> >> Пробовал различные варианты задания IFS: IFS=; IFS=''; IFS=$'\0'; >> IFS=$(echo -en "\0") и т.д., но это не решает проблему. >> >> Как обойти проблему с помощью того же xargs или while/read я знаю. Меня >> интересует почему не работает вариант с for. Подозреваю, что я где-то >> заблуждаюсь и потому у меня не работает - может кто-то подскажет в чем >> моя ошибка? >> >> -- >> WBR, Andrey Tataranovich >> > Как я понимаю, ноги растут из языка С. Да и в стандарте POSIX [1]: > строка не может содержать \0, а может только заканчиваться на \0. > Так что bash строго следует стандарту и в результате > $(seq 1 10 | tr '\n' '\0') дает с точки зрения стандарта > «плохую» строку о чем честно и предупреждает: > command substitution: ignored null byte in input > for и IFS не при чем, можете попробовать в bash и zsh: > echo $(seq 9 | tr '\n' '\0') > Ю. > [1] > http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_92 Здравый смысл подсказывает, что эта ссылка - гвоздь не от той стенки. Потому что в POSIX написано иное: строка - это то, что заканчивается нулевым байтом, включая оный байт. Таким образом, упомянутый input строкой POSIX не является - он практически никогда не содержит нулевой байт вообще. Он заканчивается по концу данных в том пайпе, в который направлен вывод команды. И поэтому применять сюда определение строки из POSIX не слишком осмыслено.