По крайней мере, в моей версии экрана¹ отправка команд через -X
в отсоединенный сеанс не работает для вещей, которые могут изменить текущее окно (например, next
или select 0
). Другие команды, такие как stuff
, работают. Может это баг, не знаю. Я подозреваю, что это «преднамеренно», поскольку флаг -Q select ...
имеет ту же проблему, и я ожидаю, что это решит именно эту проблему, если бы это было возможно.
У меня есть решение указанной вами проблемы ниже, но я думаю, что вы можете решить свою настоящую проблему следующим образом:
screen -S mysession -p 0 -X stuff 'some commands for your torrents'
Здесь мы не меняем активное окно, а отправляем команды конкретному окну (в данном случае 0
), используя опцию -p
.
Другой, более дерзкий ответ: «используйте tmux
— у него лучше поддержка скриптов» (:
¹ версия 4.06.02 (GNU) 23 октября 2017 г.
Надеюсь, это решит вашу проблему, но я пришел сюда, потому что мне действительно нужно изменить активное окно в сеансе экрана с помощью сценария.
И, пытаясь решить вашу проблему, я нашел решение для себя, поэтому я добавлю это здесь, если другие заинтересуются.
Обратите внимание, что если вы подключены вручную через какой-либо терминал, то вы можете отправлять команды next
и select
через -X
в скрипте. Но, конечно, мы не хотим подключаться вручную; мы хотим автоматизировать это.
Так что... готовьтесь к мерзости (:
Мы будем использовать отдельный сеанс экрана для подключения к интересующему нас сеансу экрана, тем самым переводя этот сеанс в состояние «прикреплено», где мы можем отправлять ему select
команд из основного скрипта. Мы будем создавать сценарии экрана внутри другого сеанса экрана со сценарием.
Предположим, у нас есть существующий сеанс с именем foo
, и мы хотим отправить ему команду select 0
. Просто запустить это не получится: screen -S foo -X select 0
.
Вместо этого сделайте что-то вроде этого:
#!/usr/bin/env bash
# (the only bash-ism here is $'\n', so you could do it with
# plain 'sh' easily, too)
# You could get this from a commandline argument, etc.
target_session=foo
# A unique name for our controller session. You could append a UUID
# if you might have two scripts running, but they would fight with
# each other anyway - probably best to avoid.
controller_session="control_$target_session"
# Create the controller session.
# It starts in detached state, so we can script against it.
screen -d -m -S "$controller_session" -t attacher
# The default window will be used for attaching to $target_session.
# We make a second window for running our "real" commands.
# We could also do this in a separate process or somesuch.
screen -S "$controller_session" -X screen -t runner
# Attach to the target session
# Note: if someone else was attached (eg: if you were watching), it
# will fail. But in that case, our subsequent command still have an
# attached session to work with, so our overall script will work.
screen -S "$controller_session" -p 0 -X stuff "screen -r '$target_session'"$'\n'
# Now that it's attached, we can run commands which change the active
# window. This is the real meat of this script, where we do the thing
# we care about.
screen -S "$controller_session" -p 1 -X stuff "screen -S '$target_session' -X select 0"$'\n'
# Hack!
# At least on my system, there needs to be some delay between the select
# command being run, and detaching. Otherwise, it does not take effect.
# 0.01 is too small, 0.05 seems to work, so this should be plenty.
sleep 0.1
# Detach from target_session
screen -S "$target_session" -X detach
# Kill the controller, since we're done with it.
screen -S "$controller_session" -X quit
Это некрасиво, но я знаю, что буду использовать это!
person
jwd
schedule
09.08.2019