Чтение путей на стандартный ввод и порождение новая интерактивная оболочка для каждой строки

Entonces, ¿está tratando de leer alguna entrada en la variable $tempy luego imprimirla junto a la fecha de hoy?

No quiere el $delante de la variable temppara el comando read:

#!/bin/bash
echo "read date yyyymmdd"
read temp
echo "${temp} + $(date '+%Y%m%d')"
0
22.05.2019, 05:56
1 ответ

Ваш сценарий Bash, кажется, делает все, как предполагалось, ему нужен только || breakпосле подоболочки, которая порождает интерактивную оболочку :таким образом, когда вы выходите из этой интерактивной оболочки с индуцированной ошибкой, такой как Ctrl+C , за которым сразу же следует Ctrl+D или команда exit 1, вы преждевременно выходите из всего конвейера.

Это, конечно, как вы заметили, приведет к выходу также, когда последняя команда, которую вы использовали из интерактивной оболочки, завершается с (нежелательной )ошибкой, но вы можете легко обойти это, выполнив простой :как последняя команда перед любым нормальным выходом или, возможно, (как возможно лучшее решение )путем проверки Ctrl+C как единственного принятый способ выхода из всего конвейера, то есть использование|| { [ $? -eq 130 ] && break; }(вместо только|| break)после подоболочки, которая порождает интерактивную оболочку.

В качестве гораздо более простого подхода, который вообще не требует ассоциативных массивов, вы можете простоuniq-получить вывод из find, как в:

find. -perm 777 -printf '%h\n' | uniq | \
(
while IFS= read -r path ; do
    (cd "${path}" && PS1="[*** REVISE \\w]: " bash --norc -i </dev/tty) || \
        { [ $? -eq 130 ] && break; }
done
)

Конечно, для этого требуется источник имен, который создает последовательные дубликаты (при наличии таковых ), как find . Или вы можете изменить их порядок, используя sort -u вместо uniq, но тогда вам придется ждать завершения sort, прежде чем вы увидите появление первой интерактивной оболочки, чего вы, кажется, не желаете.

Давайте рассмотрим подход, основанный на сценариях Python.

Вы не говорите, как вы его вызываете, но если вы используете его через канал, как в:

names-source-cmd | visit-paths.py

тогда вы используете stdin для двух противоречащих друг другу целей :ввода для имен и ввода для вашей функции Python input().

Затем вы можете скорее вызвать свой скрипт Python, как в:

names-source-cmd | visit-paths.py /dev/fd/3 3<&0 < /dev/tty

Обратите внимание на перенаправления, сделанные в приведенном выше примере :мы сначала перенаправляем только что -созданный канал (, который будет стандартным вводом в этой части конвейера ), в произвольный файл -дескриптор 3 и затем снова откройте стандартный ввод для tty, чтобы сценарий Python мог использовать его для своей функции input(). Дескриптор файла -3 затем используется в качестве источника имен через аргумент вашего скрипта Python.

Вы также можете рассмотреть следующее доказательство -концепции -:

find | \
(
while IFS= read -ru 3 name; do
    echo "name is ${name}"
    read -p "Continue ? " && [ "$REPLY" = y ] || break
done 3<&0 < /dev/tty
)

В приведенном выше примере используется тот же прием перенаправления. Поэтому вы можете использовать его для своего собственного сценария Bash, который кэширует увиденные пути в ассоциативных массивах и порождает интерактивную оболочку для каждого вновь увиденного пути.

1
28.04.2021, 23:35

Теги

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