У меня есть сценарий жемчуга, script.pl, который, когда выполнено, делает ветвление, родительский процесс производит свой pid в файл, затем выходит, в то время как дочерний процесс производит что-то к КРЕПКОМУ и затем входит некоторое время в цикл.
$pid = fork();
if ( ! defined $pid )
{
die "Failed to fork.";
}
#Parent process
elsif($pid)
{
if(!open (PID, ">>running_PIDs"))
{
warn "Error opening file to append PID";
}
print PID "$pid \n";
close PID;
}
#child process
else
{
print "Output started";
while($loopControl)
{
#Do some stuff
}
}
Это хорошо работает, когда я называю его локально т.е.: жемчуг script.pl.
Сценарий распечатывает некоторые вещи, затем возвращает управление назад оболочке. (в то время как дочерний процесс уходит в свой цикл в фоновом режиме).
Однако, когда я звоню, это через управление ssh никогда не возвращается назад к оболочке (и при этом "Вывод не запускается" строка, никогда распечатанная.
т.е.: $ ssh username@example.com 'жемчуг script.pl'
Однако интересная вещь, дочерний процесс действительно работает (я вижу его, когда я ввожу PS).
Кто-либо может объяснить, что продолжается?
Править:
Я выполнил его при отладке и получил это:
Разветвленные ###, но не знают, как создать новый TTY.Начиная с двух борьбы отладчиков за тот же TTY сильно запутан вход.
Я знаю, как переключить вывод на другое окно в xterms и консолях OS/2 только. Для ручного переключателя, поставленного имя созданного TTY в $DB:: fork_TTY, или определяют функциональный DB:: get_fork_TTY () возвращающий это.
В подобных UNIX системах можно получить название TTY для данного окна путем ввода tty и разъединить оболочку от TTY сном 1000000.
Всякий раз, когда вы запускаете фоновые задания с помощью неинтерактивных команд ssh, вам необходимо закрыть или иным образом связать stdin, stdout и stderr. В противном случае ssh будет ждать завершения фонового процесса. FAQ.
Это называется отключением или отсоединением от управляющего терминала и является общей лучшей практикой при написании фоновых заданий, не только для SSH.
Итак, самое простое изменение, не отключающее всю команду, это добавить:
#close std fds inherited from parent
close STDIN;
close STDOUT;
close STDERR;
сразу после print "Output started";
. Если дочернему процессу необходимо периодически печатать вывод во время его работы, то вместо этого вам нужно перенаправить вывод в файл журнала.
ssh username@example.com 'nohup perl script.pl'
Вы не можете выйти, потому что процесс все еще подключен. Вам нужно nohup
его.
Что происходит, так это то, что ssh выполняет 'perl script.pl' напрямую как команду. Если у вас есть 'screen', вы можете сделать:
$ ssh username@example.com 'screen -d -m perl script.pl'
, чтобы он работал на отдельном экране, и подключите его позже с помощью screen -r