Here Strings: Что здесь происходит?

Я относительно новичок в написании сценариев оболочки, но не в программировании, хотя и признаюсь, что некоторое время отсутствовал в игре.

Пытаясь понять причину ошибки в скрипте Bash, я привел три коротких примера моего использования подстановки процесса и "здесь строки", которые подают STDIN для while петли, чтобы избежать проблем подоболочки.

Я отделяю find вывод, чтобы избежать потенциальной борьбы с необычными символами имени файла.

Этот пример прекрасно работает и выводит имена всех папок в корне:

#!/bin/bash
while IFS= read -r -d '' y; do echo "${y}"
done < <(find / -type d -maxdepth 1 -mindepth 1 -printf "%P\0" | sort -z)

Этот пример тоже отлично работает:

#!/bin/bash
find / -type d -maxdepth 1 -mindepth 1 -printf "%P\0" | sort -z | \
{ while IFS= read -r -d '' y; do echo "${y}"; done }

Но это тот случай, когда я храню find вывод в строку x и попытка использовать его в качестве источника моей "здесь строки", ничего не выводит:

#!/bin/bash
x=$(find / -type d -maxdepth 1 -mindepth 1 -printf "%P\0" | sort -z)
while IFS= read -r -d '' y; do echo "${y}"; done <<< "${x}"

Какую тонкость (или плотность с моей стороны) мне здесь не хватает?

Я использую GNU bash 4.1.7(2)-релиз.

2 ответа

Решение

Строки в bash похожи на C-строки и заканчиваются нулем. Это должно объяснить, почему это не работает, когда вы пытаетесь присвоить вывод переменной.

В качестве эксперимента вы можете попробовать

a=$'foo\0bar'
echo "$a"

Когда вы назначаете строку параметру, конец строки заканчивается первым нулевым символом. Однако оболочка может передавать строки, содержащие нулевые символы, через стандартный ввод, который может считывать произвольный поток байтов.

Другие вопросы по тегам