(bash) Сценарий A, ждет сценарий B, но не его дочерний процесс

Вы можете использовать мой del:

http://fex.belwue.de/fstools/del.html

del перемещает файлы в подкаталог .del / (и обратно)

usage: del [-v] [-u] file(s)
       del [-v] -p [-r] [-d days] [directory]
       del [-v] -l
options: -v   verbose mode
         -u   undelete file(s)
         -p   purge deleted files [older than -d days]
         -r   recursive (all subdirectories)
         -l   list deleted files
examples: del *.tmp         # delete all *.tmp files
          del -u project.pl # undelete project.pl
          del -vprd 2       # verbose purge deleted files older than 2 days

9
27.07.2017, 17:27
5 ответов

Проблема здесь в том, что sshdждет конца -файла -в канале, он читает стандартный вывод команды (, а не стандартный вывод по какой-то причине, по крайней мере, с версией, которую я тестирование по )с. И фоновое задание наследует fd для этого канала.

Таким образом, чтобы обойти это, перенаправьте вывод этой фоновой команды rsyncв какой-либо файл или /dev/null, если вам это не нужно. Вы также должны перенаправить stderr, потому что даже если sshd не ожидает соответствующего канала, после выхода sshdканал будет сломан, поэтому rsyncбудет убит, если он попытается записать на stderr.

Так:

rsync... > /dev/null 2>&1 &

Сравните:

$ time ssh localhost 'sleep 2 &'
ssh localhost 'sleep 2 &'  0.05s user 0.00s system 2% cpu 2.365 total
$ time ssh localhost 'sleep 2 > /dev/null &'
ssh localhost 'sleep 2 > /dev/null &'  0.04s user 0.00s system 12% cpu 0.349 total

И:

$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null &'; sleep 2; cat out
141  # ls by killed with SIGPIPE upon writing the error message
$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null 2>&1 &'; sleep 2; cat out
2    # ls exited normally after writing the error on /dev/null instead
     # of a broken pipe
16
27.01.2020, 20:04

Напишите сценарий, который является родительским для обоих, тогда вы сможете легко управлять обоими . Альтернативно установить канал связи между двумя каналами .

Чтобы специально игнорировать определенные фоновые задания, вы можете зафиксировать PID($!— это PID последнего фонового задания )и wait $pidожидать только завершения этого задания.

4
27.01.2020, 20:04

Вы можете попробовать это. $!— это переменная оболочки по умолчанию, которая содержит идентификатор процесса последнего запущенного фонового конвейера/процесса.

command1 &
lpid1=$!

command2 &
lpid2=$!

command3 &
lpid=$!

wait $lpid1  # waits for only the process with PID lpid1  to complete. 

Вам нужно использовать это в соответствии с вашим скриптом, используя переменную exportи т. д.

1
27.01.2020, 20:04

B просто нужно дождаться собственных фоновых процессов:

rsync -av /important/stuff/. remoteserver:/remote/dir/.
rsync -av /not/so/important/stuff/. remoteserver:/remote/dir/. &
wait
exit
1
27.01.2020, 20:04

Это известная проблема сервера OpenSSH, описанная и обсуждаемая в вышестоящем bugzilla #2071 . В баге предлагается несколько обходных путей как на стороне OpenSSH, так и для скрипта.

Если вы хотите дождаться вывода скриптов, вы также должны добавить waitперед exitиз scriptB.

Если вас не волнует вывод, используйте некоторые варианты nohupи перенаправление ввода-вывода на /dev/null, что решит проблему таким же образом.

2
27.01.2020, 20:04

Теги

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