Вам нужно cd
из каждого подкаталога, прежде чем пробовать следующий. Вставка ...
cd ..
в конце цикла исправит это для подкаталогов, но сломается, когда вы сделаете это сначала в верхнем каталоге. cd ..
оттуда переместит вас на другой уровень, так что другие каталоги больше не будут видны.
Вы можете решить все это, сохраняя верхний каталог в переменной и каждый раз cd
туда:
#!/bin/bash
TOPDIR="$PWD"
for X in "$PWD" * ;
do
if [ -d "$X" ] ;
then
cd "$X"
files="$(ls)"
echo "$files" >> filesNames.txt
cd "$TOPDIR"
fi
done
Вы также можете изменить >>
на >
, если вы не хотите сохранять все результаты предыдущих запусков.
Ваша проблема в том, что Bash и Dash имеют встроенный echo
, но две реализации не ведут себя одинаково, если дана строка, содержащая \
:
echo 'abc\ndef'
Это дает разные результаты для двух командных интерпретаторов.
Вы можете получить согласованный вывод, используя printf '% s \ n'
; хотя это также встроенная функция, она производит одинаковый вывод в обеих оболочках (это не верно для всех преобразований, например, bash обеспечивает преобразование % q
, чего нет в тире):
printf '%s\n' 'abc\ndef'
Это дает ] abc \ ndef
в обеих оболочках.
Вы также можете использовать внешнюю реализацию echo
; в Linux coreutils
дает вам GNU echo в / bin / echo
:
/bin/echo 'abc\ndef'
Обратите внимание, однако, что это менее переносимо. В информационном файле GNU говорится следующее:
POSIX не требует поддержки каких-либо параметров и говорит, что поведение для
echo
определяется реализацией, если какая-либо строка содержит {{ 1}} обратная косая черта или если первый аргумент --n
. Переносимые программы могут использовать командуprintf
, если им нужно опустить завершающие символы новой строки или вывести управляющие символы или обратную косую черту.
Вместо этого вы используете printf
с вашей переменной в качестве строки форматирования. это значение, интерполированное строкой форматирования.
Используйте echo
или printf
так, как это было задумано. Вот несколько примеров:
A="abc\nde fg" B="abc\\nde fg" C="abc\\\nde fg"
echo "$A"
abc\nde fg
echo "$B"
abc\nde fg
echo "$C"
abc\\nde fg
printf "%s\n" "$A"
abc\nde fg
printf "Here is variable B: %s\n" "$B"
Here is variable B: abc\nde fg
printf "> %s <\n" "$C"
> abc\\nde fg <
Между прочим, при использовании строк в двойных кавычках они анализируются и обрабатывается символ обратной косой черты \
. Если вы определяете переменные с одинарными кавычками, весь набор \
символов также может быть сохранен:
A='abc\nde fg' B='abc\\nde fg' C='abc\\\nde fg'
echo "$A"
abc\nde fg
echo "$B"
abc\\nde fg
echo "$C"
abc\\\nde fg
Нет, существует множество вариантов echo
. echo
не переносимая команда.
dash
echo
на самом деле является одной из немногих echo
реализаций, совместимых с UNIX (по крайней мере в этом отношении; dash
не является с учетом многобайтности, существуют и другие области, в которых он несовместим с системами, поддерживающими, например, многобайтовые языковые стандарты).
Спецификация UNIX требует, чтобы
echo '\n'
выводил два символа новой строки и
echo -e x
выводил -e x
.
В то время как некоторые другие оболочки, такие как AT&T ksh
, bash
, yash
или zsh
, имеют настройки для изменения поведения их ] echo
(поведение команды GNU echo
также может зависеть от среды), в настоящее время это не относится к dash
.
В любом случае вы не хотите использовать echo
для вывода произвольных данных. Стандартная и переносимая команда для этого - printf
.
Вы можете найти более подробную информацию, в том числе о том, как реализовать другое echo
как функцию-оболочку вокруг printf
at в ответе на Почему printf лучше, чем echo?