Почему все NUL удалены из моего script?

Кажется, что bash, а также тире, отфильтруйте любой ASCII NUL из моих скриптов.

$ printf 'test="\000a" ; echo ${#test}' | sh
1
$ printf 'test="\001a" ; echo ${#test}' | sh
2
$ printf 'ec\000ho test' | sh
test
$ # (Same for bash)

Хотя я согласен с тем, что использование NUL - плохая плохая идея (например, передача аргументов в программы работает с NUL-завершаемыми строками), я не вижу, где это поведение санкционировано стандарт POSIX.

Это становится еще хуже, когда это поведение решает синтаксическую корректность файла.

$ printf 'echo "\\\000"' | sh
sh: Syntax error: Unterminated quoted string
$ printf 'echo "\\\000"' | bash
bash: line 1: unexpected EOF while looking for matching `"'
bash: line 2: syntax error: unexpected end of file
$ printf 'echo "\\\134"' | sh
\

Какую существенную часть я пропустил, или это NUL-удаление только решение о том, как справиться с неуказанным поведением?

Ответ 1

Раздел INPUT FILES в стандарте для sh гласит:

Входной файл должен быть текстовым файлом, за исключением того, что длина строк не ограничена. Если входной файл пуст или состоит только из пустых строк или комментариев или обоих, sh должен выйти с нулевым статусом выхода.

Термин "текстовый файл" определен в разделе 3.395 здесь как:

Файл, содержащий символы, помещенные в ноль или более строк. Строки не содержат символов NUL, и ни один из них не может превышать длину {LINE_MAX} байтов, включая <newline> персонаж. Хотя POSIX.1-2008 не различает текстовые файлы и двоичные файлы (см. Стандарт ISO C), многие утилиты производят только предсказуемый или значимый вывод при работе с текстовыми файлами. Стандартные утилиты, которые имеют такие ограничения, всегда указывают "текстовые файлы" в разделах STDIN или INPUT FILES

Если вход не является текстовым файлом (которого нет, если он содержит нулевые байты), поведение не имеет смысла и не предсказуемо.