Re: Null в качестве разделителя в скриптеA
yuri.nefedov@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 не слишком осмыслено.
Reply to: