сеанс открытия экрана на многих удаленных хостах, выполняющий сложную команду, после этого не выходить - PullRequest
1 голос
/ 27 мая 2020

У меня длинный список удаленных хостов, и я хочу запустить команду оболочки на всех из них. Команда занимает очень много времени, поэтому я хочу запустить команду внутри screen на удаленном компьютере , немедленно отключившись от каждого, и я хочу, чтобы вывод терминала на пульте дистанционного управления сохранялся после команды выходы. Существует «тег», который должен быть указан для каждой команды в качестве аргумента. Я пытался сделать это с помощью parallel, примерно так:

$ cat servers.txt
user1@server1.example.com/tag1
user2@server2.example.com/tag2
# ...

$ cat run.sh
grep -v '^#' servers.txt |
    parallel ssh -tt '{//}' \
        'tag={/}; exec screen slow_command --option1 --option2 $tag other args'

Это не работает: все удаленные процессы запущены, но они не отсоединены (поэтому сеансы s sh оставаться в рабочем состоянии, и моя локальная оболочка не возвращается), и как только каждая команда завершается, ее экран немедленно закрывается, и вывод теряется.

Как мне исправить этот сценарий? Примечание: если это проще сделать с помощью tmux и / или какой-либо другой программы маршаллинга помимо parallel, я буду рад услышать ответы, объясняющие, как это сделать таким образом.

1 Ответ

0 голосов
/ 27 мая 2020

Примерно так:

grep -v '^#' servers.txt |
  parallel -q --colsep / ssh {1} "screen -d -m bash -c 'echo do stuff \"{2}\";sleep 1000000'"

Последний sleep гарантирует, что экран не d ie. У вас будет 1000000 секунд, чтобы присоединиться к нему и убить его.

Там очень много цитат, особенно если do stuff сложный.

Может быть проще создать функцию который вычисляет tag на удаленном компьютере. Для этого вам понадобится GNU Parallel 20200522:

env_parallel --session

f() {
  sshlogin="$1"
  # TODO given $sshlogin compute $tag (e.g. a table lookup)
  do_stuff() {
     echo "do stuff $tag"
     sleep 1000000
  }
  export -f do_stuff
  screen -d -m bash -c do_stuff "$@"
}

env_parallel  --nonall --slf servers_without_tag f '$PARALLEL_SSHLOGIN' 

env_parallel --endsession
...