[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: