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"
Когда вы назначаете строку параметру, конец строки заканчивается первым нулевым символом. Однако оболочка может передавать строки, содержащие нулевые символы, через стандартный ввод, который может считывать произвольный поток байтов.