chroot
реализовано ядром , отдельно от пространств имен и контрольных групп. Пространства имен монтирования и pivot_root
могут использоваться для обеспечения той же функциональности, что и chroot
; см. Как выполнить chroot с пространствами имен Linux?
Механизм Docker использует chroot
.
Думаю, проблема в неправильном синтаксисе подстановки команд.
Команда
num=$(( expression ))
интерпретирует содержимое скобок как арифметическое выражение и присваивает числовой результат num
. Он , а не вернет результат выполнения того, что написано в скобках в виде кода. Скорее, ls
,wc
и l
будут интерпретироваться как переменные оболочки, и будет выполнена операция «$ls
ИЛИ $wc
минус $l
», результатом которой будет ноль, поскольку ни одна из этих «переменных» не инициализирована.
То, что вы, вероятно, пытаетесь сделать, будет записано как
num="$(ls | wc -l)"
Однако даже в этом случае синтаксический анализ выводаls
в целом не является хорошей идеей. Скорее посмотрите на некоторые ответы на этот аналогичный вопрос , где представлены «надежные» решения, которые также будут работать, когда имена файлов содержат специальные символы.
Чтобы найти количество имен в одном каталоге, разверните в нем глобус *
и подсчитайте количество сгенерированных слов:
shopt -s nullglob # to make the * glob expand to nothing
# if there is no matching names
set -- *
num=$#
printf '%s\n' "$num"
Специальное значение $#
— это количество позиционных параметров. Команда set
устанавливает позиционные параметры.
Если вы хотите подсчитывать только обычные файлы и включать скрытые имена, используйте
shopt -s nullglob dotglob
for name in *; do
if [ ! -f "$name" ] || [ -L "$name" ]; then
# skip non-regular files and symbolic links
continue
fi
files+=( "$name" )
done
num=${#files[@]}
printf '%s\n' "$num"
Чтобы сделать это рекурсивно в подкаталогах, также установите параметр оболочки globstar
и используйте **/*
в качестве шаблона подстановки.
(в оболочке zsh
, достаточно было быset -- **/*(.DN); print $#
)
Проблема с вашим
num=$(( ls | wc -l ))
двоится:
$((... ))
— арифметическое расширение. Вы, вероятно, хотите заменить команду здесь, $(... )
. wc -l
не будет считать файлы. Он будет подсчитывать количество символов новой строки, выводимых ls
. Файл с одним или несколькими символами новой строки в имени будет считаться несколькими файлами по wc -l
. Вы можете проверить это, создав такой файл с помощью touch $'hello\nworld'
. Если вы хотите подсчитывать файлы, включая скрытые файлы (.*
), но исключая подкаталоги, вы можете использовать:
find. -maxdepth 1 -type f -printf '.' | wc -c
Можно использовать все преимущества find
.