Запустить скрипт на новом экране, если true - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть скрипт, где он будет проверять, является ли background_logging значением true, если это так, то я хочу, чтобы остальная часть скрипта запускалась на новом отдельном экране.

Я пытался использовать это: exec screen -dmS "alt-logging" /bin/bash "$0";.Иногда это создает экран и т. Д., Но иногда ничего не происходит вообще.Когда он создает экран, он не запускает остальную часть файла сценария, и когда я пытаюсь возобновить экран, он говорит, что он (Dead??).

Вот весь сценарий, я добавил несколько комментариевчтобы лучше объяснить, что я хочу сделать:

#!/bin/bash

# Configuration files
config='config.cfg'
source "$config"

# If this is true, run the rest of the script in a new screen.
# $background_logging comes from the configuration file declared above (config).
if [ $background_logging == "true" ]; then
    exec screen -dmS "alt-logging" /bin/bash "$0";
fi

[ $# -eq 0 ] && { echo -e "\nERROR: You must specify an alt file!"; exit 1; }

# Logging script
y=0
while IFS='' read -r line || [[ -n "$line" ]]; do
    cmd="screen -dmS alt$y bash -c 'exec $line;'"
    eval $cmd
    sleep $logging_speed
    y=$(( $y + 1 ))
done < "$1"

Вот содержимое файла конфигурации:

# This is the speed at which alts will be logged, set to 0 for fast launch.
logging_speed=5
# This is to make a new screen in which the script will run.
background_logging=true

Цель этого скрипта - пройти по каждой строке в тексте.файл и выполнить строку в качестве команды.Он отлично работает, когда $background_logging равен false, поэтому с циклом while проблем нет.

1 Ответ

0 голосов
/ 16 декабря 2018

Как описано, это не совсем возможно.Конкретно, что происходит в вашем скрипте: когда вы exec заменяете свой код запущенного скрипта на код экрана.

Что вы можете сделать, так это запустить экран, выяснить несколькоподробности об этом и перенаправьте ваши консольные скрипты в / вывод на него, но вы не сможете переписать ваш запущенный скрипт к экранному процессу, как если бы он там начался.Примерно так:

#!/bin/bash

# Use a temp file to pass cat's parent pid out of screen.
tempfile=$(tempfile)
screen -dmS 'alt-logging' /bin/bash -c "echo \$\$ > \"${tempfile}\" && /bin/cat"

# Wait to receive that information on the outside (it may not be available
# immediately).
while [[ -z "${child_cat_pid}" ]] ; do
        child_cat_pid=$(cat "${tempfile}")
done

# point stdin/out/err of the current shell (rest of the script) to that cat
# child process

exec 0< /proc/${child_cat_pid}/fd/0
exec 1> /proc/${child_cat_pid}/fd/1
exec 2> /proc/${child_cat_pid}/fd/2

# Rest of the script
i=0
while true ; do
    echo $((i++))
    sleep 1
done

Далеко не идеально и довольно грязно.Вероятно, это может помочь использование стороннего инструмента, такого как reptyr , для захвата консоли скрипта изнутри экрана.Но все же более простым и понятным будет (при желании) запускать код, который должен быть выполнен в этом сеансе экрана после его установки.

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

...